From 9a5ea0bf479d45d625b0c280d4662e6bfea8932b Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 14 Nov 2018 23:57:41 +0200 Subject: [PATCH] Initial --- build.xml | 83 ++ nbproject/build-impl.xml | 1251 +++++++++++++++++++++ nbproject/genfiles.properties | 8 + nbproject/private/private.properties | 8 + nbproject/private/private.xml | 5 + nbproject/project.properties | 168 +++ nbproject/project.xml | 23 + src/org/pabloid/tank/ImageLoader.java | 175 +++ src/org/pabloid/tank/Loading.java | 93 ++ src/org/pabloid/tank/Missile.java | 69 ++ src/org/pabloid/tank/Scale.java | 118 ++ src/org/pabloid/tank/Settings.java | 118 ++ src/org/pabloid/tank/Tank.java | 523 +++++++++ src/org/pabloid/tank/TankCanvas.java | 1491 +++++++++++++++++++++++++ src/res/about.txt | 41 + src/res/bomb.png | Bin 0 -> 206 bytes src/res/boom.png | Bin 0 -> 322 bytes src/res/car.png | Bin 0 -> 1076 bytes src/res/cross.png | Bin 0 -> 248 bytes src/res/fuel.png | Bin 0 -> 176 bytes src/res/live.png | Bin 0 -> 156 bytes src/res/man.png | Bin 0 -> 228 bytes src/res/mis.png | Bin 0 -> 144 bytes src/res/swiborg.png | Bin 0 -> 770 bytes src/res/tank.png | Bin 0 -> 373 bytes src/res/tick.png | Bin 0 -> 200 bytes 26 files changed, 4174 insertions(+) create mode 100644 build.xml create mode 100644 nbproject/build-impl.xml create mode 100644 nbproject/genfiles.properties create mode 100644 nbproject/private/private.properties create mode 100644 nbproject/private/private.xml create mode 100644 nbproject/project.properties create mode 100644 nbproject/project.xml create mode 100644 src/org/pabloid/tank/ImageLoader.java create mode 100644 src/org/pabloid/tank/Loading.java create mode 100644 src/org/pabloid/tank/Missile.java create mode 100644 src/org/pabloid/tank/Scale.java create mode 100644 src/org/pabloid/tank/Settings.java create mode 100644 src/org/pabloid/tank/Tank.java create mode 100644 src/org/pabloid/tank/TankCanvas.java create mode 100644 src/res/about.txt create mode 100644 src/res/bomb.png create mode 100644 src/res/boom.png create mode 100644 src/res/car.png create mode 100644 src/res/cross.png create mode 100644 src/res/fuel.png create mode 100644 src/res/live.png create mode 100644 src/res/man.png create mode 100644 src/res/mis.png create mode 100644 src/res/swiborg.png create mode 100644 src/res/tank.png create mode 100644 src/res/tick.png diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..92f624e --- /dev/null +++ b/build.xml @@ -0,0 +1,83 @@ + + + + + + Builds, tests, and runs the project . + + + diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml new file mode 100644 index 0000000..192fb74 --- /dev/null +++ b/nbproject/build-impl.xml @@ -0,0 +1,1251 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Classpath to J2ME Ant extension library (libs.j2me_ant_ext.classpath property) is not set. For example: location of mobility/modules/org-netbeans-mobility-antext.jar file in the IDE installation directory. + Platform home (platform.home property) is not set. Value of this property should be ${platform.active.description} emulator home directory location. + Platform boot classpath (platform.bootclasspath property) is not set. Value of this property should be ${platform.active.description} emulator boot classpath containing all J2ME classes provided by emulator. + Must set src.dir + Must set build.dir + Must set dist.dir + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set preprocessed.dir + + + + + + + + + + + + + + + + + + Must set build.classes.dir + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + Must set obfuscated.classes.dir + + + + Must set obfuscated.classes.dir + Must set obfuscator.srcjar + Must set obfuscator.destjar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set preverify.classes.dir + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MicroEdition-Configuration: ${platform.configuration} + + MicroEdition-Configuration: ${platform.configuration} + + + + MicroEdition-Profile: ${platform.profile} + + MicroEdition-Profile: ${platform.profile} + + + + Must set dist.jad + + + + + + + + + + + + + + + + + + + + + + + + ${manifest.midlets}${evaluated.manifest.apipermissions}${evaluated.manifest.pushregistry}${manifest.others}${manifest.jad} + ${manifest.midlets}${evaluated.manifest.apipermissions}${evaluated.manifest.pushregistry}${manifest.others}${manifest.manifest} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Starting emulator with port number ${active.debug.port} + + + + + + + + + + + + + + + + + Starting emulator with port number ${active.debug.port} + + + + + + + + + + + + + + + + + Must set dist.javadoc.dir + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${all.configurations} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Property deployment.${deployment.method}.scriptfile not set. The property should point to an Ant script providing ${deployment.method} deployment. + + + + + + + + Classpath to Ant Contrib library (libs.ant-contrib.classpath property) is not set. + + + + + + + + + Active project configuration: @{cfg} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Property build.root.dir is not set. By default its value should be \"build\". + Property dist.root.dir is not set. By default its value should be \"dist\". + + + + + diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties new file mode 100644 index 0000000..f7aae39 --- /dev/null +++ b/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +build.xml.data.CRC32=ff7d85e0 +build.xml.script.CRC32=a6631c98 +build.xml.stylesheet.CRC32=9c6a911d +nbproject/build-impl.xml.data.CRC32=ff7d85e0 +nbproject/build-impl.xml.script.CRC32=59b1617a +nbproject/build-impl.xml.stylesheet.CRC32=e46c2d22 diff --git a/nbproject/private/private.properties b/nbproject/private/private.properties new file mode 100644 index 0000000..7669848 --- /dev/null +++ b/nbproject/private/private.properties @@ -0,0 +1,8 @@ +#Tue, 15 Mar 2011 16:10:11 +0300 +#Fri May 07 21:10:28 VOLST 2010 +netbeans.user=C:\\Users\\aNNiMON\\AppData\\Roaming\\NetBeans\\dev +javadoc.preview=true +config.active=Release +deployment.counter=129 +app-version.autoincrement=true +deployment.number=0.1.28 diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml new file mode 100644 index 0000000..8505fc1 --- /dev/null +++ b/nbproject/private/private.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/nbproject/project.properties b/nbproject/project.properties new file mode 100644 index 0000000..e0c117b --- /dev/null +++ b/nbproject/project.properties @@ -0,0 +1,168 @@ +abilities=MMAPI=1.1,SATSAJCRMI=1.0,SATSACRYPTO=1.0,JSR82=1.1,JSR226=1.0,MIDP=2.1,JSR229=1.1.0,SATSAAPDU=1.0,CLDC=1.1,JSR177=1.0,JSR179=1.0.1,J2MEWS=1.0,WMA=2.0,JSR172=1.0,OBEX=1.0,ColorScreen,JSR238=1.0,JSR239=1.0,JSR211=1.0,JSR234=1.0,ScreenWidth=240,JSR75=1.0,JSR184=1.1,SATSAPKI=1.0,ScreenHeight=320,ScreenColorDepth=8,JSR180=1.0.1,J2MEXMLRPC=1.0, +all.configurations=\ ,NoBluetooth,Release +application.args= +application.description= +application.description.detail= +application.name= +application.vendor=Vendor +build.classes.dir=${build.dir}/compiled +build.classes.excludes=**/*.java,**/*.form,**/*.class,**/.nbintdb,**/*.mvd,**/*.wsclient,**/*.vmd +build.dir=build/${config.active} +build.root.dir=build +configs.NoBluetooth.debug.level=debug +configs.NoBluetooth.filter.exclude.tests=false +configs.NoBluetooth.filter.excludes=res/btank.png +configs.NoBluetooth.filter.more.excludes=**/overview.html,**/package.html +configs.NoBluetooth.filter.use.standard=true +configs.NoBluetooth.javac.debug=false +configs.NoBluetooth.javac.deprecation=false +configs.NoBluetooth.javac.encoding=UTF-8 +configs.NoBluetooth.javac.optimize=true +configs.NoBluetooth.obfuscation.custom= +configs.NoBluetooth.obfuscation.level=9 +configs.Release.abilities=MMAPI=1.1,JSR82=1.1,JSR280=1.0,JSR226=1.0,MIDP=2.1,JSR229=1.1,SATSA=1.0,CLDC=1.1,JSR177=1.0,JSR179=1.0,RELEASE=,J2MEWS=1.0,WMA=2.0,JSR172=1.0,JSR256=1.0,ColorScreen,OBEX=1.0,JSR238=1.0,JSR239=1.0,JSR211=1.0,JSR234=1.0,ScreenWidth=240,JSR75=1.0,JSR184=1.1,ScreenHeight=320,ScreenColorDepth=16,JSR180=1.1.0 +configs.Release.debug.level=debug +configs.Release.filter.exclude.tests=true +configs.Release.filter.excludes= +configs.Release.filter.more.excludes=**/overview.html,**/package.html +configs.Release.filter.use.standard=true +configs.Release.javac.debug=true +configs.Release.javac.deprecation=false +configs.Release.javac.encoding=UTF-8 +configs.Release.javac.optimize=true +configs.Release.obfuscation.custom= +configs.Release.obfuscation.level=9 +debug.level=debug +debugger.timeout= +deployment.copy.target=deploy +deployment.instance=default +deployment.jarurl=${dist.jar} +deployment.method=NONE +deployment.override.jarurl=false +dist.dir=dist/${config.active} +dist.jad=Tank.jad +dist.jar=Tank.jar +dist.javadoc.dir=${dist.dir}/doc +dist.root.dir=dist +extra.classpath= +file.reference.builtin.ks=${netbeans.user}/config/j2me/builtin.ks +filter.exclude.tests=false +filter.excludes= +filter.more.excludes=**/overview.html,**/package.html +filter.use.standard=true +jar.compress=true +javac.debug=true +javac.deprecation=false +javac.encoding=UTF-8 +javac.optimize=true +javac.source=1.3 +javac.target=1.3 +javadoc.author=false +javadoc.encoding= +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +libs.classpath=${reference.PLib.jar} +main.class= +main.class.class=applet +manifest.apipermissions= +manifest.file=manifest.mf +manifest.is.liblet=false +manifest.jad= +manifest.manifest= +manifest.midlets=MIDlet-1: Tank,/res/tank.png,org.pabloid.tank.Tank\n +manifest.others=MIDlet-Vendor: P@bloid\nMIDlet-Name: Tank\nMIDlet-Icon: /res/tank.png\nMIDlet-Version: ${deployment.number}\n +manifest.pushregistry= +name=Tank +no.dependencies=false +nokiaS80.application.icon= +nsicom.application.monitorhost= +nsicom.application.runremote= +nsicom.application.runverbose= +nsicom.remoteapp.location=\\My Documents\\NetBeans Applications +nsicom.remotevm.location=\\Windows\\creme\\bin\\CrEme.exe +obfuscated.classes.dir=${build.dir}/obfuscated +obfuscation.custom= +obfuscation.level=0 +obfuscator.destjar=${build.dir}/obfuscated.jar +obfuscator.srcjar=${build.dir}/before-obfuscation.jar +platform.active=Sony_Ericsson_SDK_2_5_0_6_for_the_Java_TM__ME_Platform_Emulator_ +platform.active.description=Sony Ericsson SDK 2.5.0.6 for the Java(TM) ME Platform(Emulator) +platform.apis=WMA-2.0,JSR238-1.0,JSR211-1.0,JSR82-1.1,JSR177-1.0,JSR234-1.0,J2ME-WS-1.0,JSR239-1.0,JSR226-1.0,JSR75-1.0,JSR184-1.1 +platform.bootclasspath=${platform.home}/lib/jsr226.jar:${platform.home}/lib/jsr238.jar:${platform.home}/lib/jsr211.jar:${platform.home}/lib/satsa-jcrmi.jar:${platform.home}/lib/jsr082.jar:${platform.home}/lib/satsa-apdu.jar:${platform.home}/lib/jsr184.jar:${platform.home}/lib/jsr239.jar:${platform.home}/lib/jsr75.jar:${platform.home}/lib/j2me-ws.jar:${platform.home}/lib/wma20.jar:${platform.home}/lib/jsr234.jar:${platform.home}/lib/cldcapi11.jar:${platform.home}/lib/midpapi20.jar +platform.configuration=CLDC-1.1 +platform.device=SonyEricsson_China_JP7_128x160_Emu +platform.fat.jar=true +platform.profile=MIDP-2.0 +platform.trigger=CLDC +platform.type=UEI-1.0.1 +preprocessed.dir=${build.dir}/preprocessed +preverify.classes.dir=${build.dir}/preverified +preverify.sources.dir=${build.dir}/preverifysrc +project.PLib=../PLib +reference.PLib.jar=${project.PLib}/dist/PLib.jar +resources.dir=resources +ricoh.application.email= +ricoh.application.fax= +ricoh.application.icon= +ricoh.application.target-jar= +ricoh.application.telephone= +ricoh.application.uid=38103365 +ricoh.application.version= +ricoh.dalp.application-desc.auto-run=false +ricoh.dalp.application-desc.energy-save= +ricoh.dalp.application-desc.exec-auth= +ricoh.dalp.application-desc.visible=true +ricoh.dalp.argument= +ricoh.dalp.codebase= +ricoh.dalp.display-mode.color=true +ricoh.dalp.display-mode.is-4line-support=false +ricoh.dalp.display-mode.is-hvga-support=true +ricoh.dalp.display-mode.is-vga-support=false +ricoh.dalp.display-mode.is-wvga-support=false +ricoh.dalp.information.abbreviation= +ricoh.dalp.information.icon.basepath= +ricoh.dalp.information.icon.location= +ricoh.dalp.information.is-icon-used=true +ricoh.dalp.install.destination=hdd +ricoh.dalp.install.mode.auto=true +ricoh.dalp.install.work-dir=hdd +ricoh.dalp.is-managed=true +ricoh.dalp.resources.dsdk.version=2.0 +ricoh.dalp.resources.jar.basepath= +ricoh.dalp.resources.jar.version= +ricoh.dalp.version= +ricoh.icon.invert=false +ricoh.platform.target.version= +run.cmd.options= +run.jvmargs= +run.method=STANDARD +run.security.domain=manufacturer +run.use.security.domain=false +savaje.application.icon= +savaje.application.icon.focused= +savaje.application.icon.small= +savaje.application.uid=TBD +savaje.bundle.base= +savaje.bundle.debug=false +savaje.bundle.debug.port= +semc.application.caps= +semc.application.icon= +semc.application.icon.count= +semc.application.icon.splash= +semc.application.icon.splash.installonly=false +semc.application.uid=E0691280 +semc.certificate.path= +semc.private.key.password= +semc.private.key.path= +sign.alias=minimal +sign.enabled=false +sign.keystore=${file.reference.builtin.ks} +src.dir=src +use.emptyapis=true +use.preprocessor=true diff --git a/nbproject/project.xml b/nbproject/project.xml new file mode 100644 index 0000000..07cbe41 --- /dev/null +++ b/nbproject/project.xml @@ -0,0 +1,23 @@ + + + org.netbeans.modules.kjava.j2meproject + + + Tank + 1.6 + + + + PLib + jar + + jar + clean + jar + + + + + + + diff --git a/src/org/pabloid/tank/ImageLoader.java b/src/org/pabloid/tank/ImageLoader.java new file mode 100644 index 0000000..e83c763 --- /dev/null +++ b/src/org/pabloid/tank/ImageLoader.java @@ -0,0 +1,175 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.pabloid.tank; + +import java.io.IOException; +import java.util.Vector; +import javax.microedition.lcdui.Graphics; +import javax.microedition.lcdui.Image; +import javax.microedition.lcdui.game.Sprite; +import org.pabloid.ui.ImageUtils; + +/** + * + * @author pabloid + */ +public class ImageLoader +{ + public static final int TRANSPARENT_COLOR = 0xff00ff; + private static final double[][] colors = + { + { + 1, 0, 0 + }, + { + 1, 0.5, 0 + }, + { + 1, 1, 0 + }, + { + 0.5, 1, 0 + }, + { + 0, 1, 0 + }, + { + 0, 1, 0.5 + }, + { + 0, 1, 1 + }, + { + 0, 0.5, 1 + }, + { + 0, 0, 1 + }, + { + 0.3, 0.3, 0.3 + } + }; + public static final int CAR_FRAMES = colors.length + 2; + public static final int ID_TANK = 0; + public static final int ID_BTANK = 1; + public static final int ID_LIVE = 2; + public static final int ID_BOMB = 3; + public static final int ID_BOOM = 4; + public static final int ID_CAR = 5; + public static final int ID_FUEL = 6; + public static final int ID_MAN = 7; + public static final int ID_MIS = 8; + public static final int ID_SWIBORG = 9; + public static final int ID_FAST_MIS = 10; + private Vector images = new Vector(); + + public ImageLoader() throws IOException + { + Image tmp = Image.createImage("/res/tank.png"); + images.addElement(tmp);//0 + int w = tmp.getWidth(), h = tmp.getHeight(); + int[] rgb = new int[w * h]; + tmp.getRGB(rgb, 0, w, 0, 0, w, h); + for (int i = 0; i < rgb.length; i++) + { + int a = rgb[i] & 0xff000000; + int r = (rgb[i] >> 8) & 0xff; + int other = rgb[i] & 0xffff; + rgb[i] = a | (r << 16) | other; + } + tmp = Image.createRGBImage(rgb, w, h, true); + images.addElement(tmp);//1 + images.addElement(fromHalf(Image.createImage("/res/live.png")));//2 + images.addElement(Image.createImage("/res/bomb.png"));//3 + tmp = Image.createImage("/res/boom.png"); + Image boom = Image.createImage(4 * 32, 32); + Graphics G = boom.getGraphics(); + G.setColor(TRANSPARENT_COLOR); + G.fillRect(0, 0, boom.getWidth(), boom.getHeight()); + for (int i = 0; i < 4; i++) + { + G.drawImage(tmp, i * 32 + 16, 16, Graphics.VCENTER | Graphics.HCENTER); + tmp = ImageUtils.resize(tmp, tmp.getWidth() / 2, tmp.getHeight() / 2); + tmp = Image.createImage(tmp, 0, 0, tmp.getWidth(), tmp.getWidth(), Sprite.TRANS_ROT90); + } + images.addElement(whiteToAlpha(boom));//4 + Image car = Image.createImage("/res/car.png"); + w = car.getWidth(); + h = car.getHeight(); + tmp = Image.createImage(w / 2 * CAR_FRAMES, h); + G = tmp.getGraphics(); + G.setColor(TRANSPARENT_COLOR); + G.fillRect(0, 0, tmp.getWidth(), tmp.getHeight()); + G.drawImage(car, tmp.getWidth(), 0, Graphics.TOP | Graphics.RIGHT); + car = Image.createImage(car, 0, 0, w / 2, h, 0); + w /= 2; + for (int i = 0; i < colors.length; i++) + G.drawImage(switchChannels(car, colors[i]), w * i, 0, 0); + images.addElement(whiteToAlpha(tmp)); + images.addElement(Image.createImage("/res/fuel.png")); + images.addElement(Image.createImage("/res/man.png")); + images.addElement(Image.createImage("/res/mis.png")); + images.addElement(fromHalf(Image.createImage("/res/swiborg.png"))); + tmp = Image.createImage(5, 5); + G = tmp.getGraphics(); + G.setColor(TRANSPARENT_COLOR); + G.fillRect(0, 0, tmp.getWidth(), tmp.getHeight()); + G.setColor(0xff0000); + G.fillArc(0, 0, 5, 5, 0, 360); + images.addElement(whiteToAlpha(tmp)); + } + + public Image get(int id) + { + return (Image) images.elementAt(id); + } + + private Image whiteToAlpha(Image src) + { + int w = src.getWidth(), h = src.getHeight(); + int[] rgb = new int[w * h]; + src.getRGB(rgb, 0, w, 0, 0, w, h); + for (int i = 0; i < rgb.length; i++) + if ((rgb[i] & 0xffffff) == TRANSPARENT_COLOR) + rgb[i] = 0; + return Image.createRGBImage(rgb, w, h, true); + } + + private Image switchChannels(Image src, double[] color) + { + int w = src.getWidth(), h = src.getHeight(); + int[] rgb = new int[w * h]; + src.getRGB(rgb, 0, w, 0, 0, w, h); + double cr = color[0]; + double cg = color[1]; + double cb = color[2]; + for (int i = 0; i < rgb.length; i++) + { + int a = rgb[i] & 0xff000000; + int r = (rgb[i] >> 16) & 0xff; + r *= cr; + int g = (rgb[i] >> 8) & 0xff; + g *= cg; + int b = (rgb[i]) & 0xff; + b *= cb; + rgb[i] = a | (r << 16) | (g << 8) | b; + } + return Image.createRGBImage(rgb, w, h, true); + } + + private Image fromHalf(Image image) + { + int w = image.getWidth(); + int h = image.getHeight(); + Image result = Image.createImage(w * 2, h); + Graphics g = result.getGraphics(); + g.setColor(TRANSPARENT_COLOR); + g.fillRect(0, 0, w * 2, h); + g.drawImage(image, 0, 0, 0); + image = Image.createImage(image, 0, 0, w, h, Sprite.TRANS_MIRROR); + g.drawImage(image, w, 0, 0); + return whiteToAlpha(result); + } +} diff --git a/src/org/pabloid/tank/Loading.java b/src/org/pabloid/tank/Loading.java new file mode 100644 index 0000000..8f00760 --- /dev/null +++ b/src/org/pabloid/tank/Loading.java @@ -0,0 +1,93 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.pabloid.tank; + +import java.io.IOException; +import javax.microedition.lcdui.Canvas; +import javax.microedition.lcdui.Graphics; +import javax.microedition.lcdui.Image; +import org.pabloid.ui.ImageUtils; + +/** + * + * @author pabloid + */ +class Loading extends Canvas implements Runnable +{ + private final int max; + private String msg = ""; + private final double coef; + private Image img; + private final int h; + private final int w; + private double index; + private Thread thread; + + Loading(int max) + { + setFullScreenMode(true); + coef = (double) (getWidth() - 10) / (double) max; + this.max = max; + this.w = getWidth(); + this.h = getHeight(); + try + { + img = Image.createImage("/res/tank.png"); + } + catch (IOException t) + { + t.printStackTrace(); + } + index = 0; + } + + protected void paint(Graphics g) + { + ImageUtils.gradient(g, 0, 0, w, h, 0xccffff, 0xffffcc, true); + g.drawImage(img, w / 2, h / 3, Graphics.HCENTER | Graphics.VCENTER); + g.setColor(0x008000); + g.drawRect(3, 2 * h / 3, w - 6, 19); + ImageUtils.gradient(g, 5, 2 * h / 3 + 2, (int) (coef * index) - 3, 16, 0x008000, 0x00ff00, true); + } + + void start() + { + if (thread == null) + thread = new Thread(this); + else + thread.interrupt(); + thread.start(); + } + + void stop() + { + if (thread != null) + thread.interrupt(); + } + + void next() + { + index++; + if (index >= max) + index = 0; + repaint(); + serviceRepaints(); + } + + public void run() + { + while (true) + { + next(); + try + { + Thread.sleep(100); + } + catch (InterruptedException t) + { + } + } + } +} diff --git a/src/org/pabloid/tank/Missile.java b/src/org/pabloid/tank/Missile.java new file mode 100644 index 0000000..df051d5 --- /dev/null +++ b/src/org/pabloid/tank/Missile.java @@ -0,0 +1,69 @@ +package org.pabloid.tank; + +import javax.microedition.lcdui.Image; + +class Missile +{ + private double x; + private double y; + private double sx; + private double sy; + private int type; + private Image image; + public int multiCount=0; + + Missile(Image img, int x, double y, double speed, int type) + { + this.x = x; + this.y = y; + if (speed < 1) + speed = 1; + this.sy = -speed; + this.sx = 0; + image = img; + this.type = type; + } + + Missile(Image img, int x, double y, double speed, int type, int angle) + { + this.x = x; + this.y = y; + if (speed < 1) + speed = 1; + this.sy = -speed * Math.sin(Math.toRadians(angle)); + this.sx = speed * Math.cos(Math.toRadians(angle)); + image = img; + this.type = type; + } + + public int getType() + { + return type; + } + + public Image getImage() + { + return image; + } + + public int getX() + { + return (int) x; + } + + public int getY() + { + return (int) y; + } + + void move() + { + y += sy; + x += sx; + } + + boolean isOut() + { + return (y < -8 || y > TankCanvas.h || x < -8 || x > TankCanvas.w); + } +} diff --git a/src/org/pabloid/tank/Scale.java b/src/org/pabloid/tank/Scale.java new file mode 100644 index 0000000..4d0aabb --- /dev/null +++ b/src/org/pabloid/tank/Scale.java @@ -0,0 +1,118 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.pabloid.tank; + +import javax.microedition.lcdui.Canvas; +import javax.microedition.lcdui.Command; +import javax.microedition.lcdui.CommandListener; +import javax.microedition.lcdui.Font; +import javax.microedition.lcdui.Graphics; +import org.pabloid.ui.ImageUtils; + +/** + * @author pabloid + */ +public class Scale extends Canvas +{ + public static Command COMMAND_SELECT = new Command("Select", Command.OK, 0); + private int index = 0, ph = Font.getDefaultFont().getHeight(); + CommandListener cl; + String message = "", text = ""; + private final int width; + private int max; + private double coef; + private double add = 1; + + public void setText(String text) + { + this.text = text; + } + + public void setMax(int max) + { + this.max = max; + coef = (double) (width - 3) / max; + index = 0; + } + + public void setMessage(String message) + { + this.message = message; + } + + public void setCommandListener(CommandListener cl) + { + this.cl = cl; + } + + public Scale(int max) + { + setFullScreenMode(true); + this.width = getWidth(); + this.max = max; + coef = (double) (width - 3) / max; + } + + /** + * paint + * @param g + */ + public void paint(Graphics g) + { + ImageUtils.gradient(g, 0, 0, getWidth(), getHeight(), 0xffffcc, 0xccffff, true); + g.setColor(0x006600); + g.drawRect(1, 4 + ph, width - 3, 19); + ImageUtils.gradient(g, 3, 6 + ph, (int) (coef * index) - 3, 16, 0x00ff00, 0x008000, true); + TankCanvas.drawHL(g, "" + index, 3, 3, 0xff0000, 0xffff00, Graphics.TOP | Graphics.LEFT); + g.setFont(Font.getFont(0, Font.STYLE_BOLD, Font.SIZE_LARGE)); + TankCanvas.drawHL(g, message, 8, getHeight() - 8, 0x990000, 0xffff99, Graphics.BASELINE | Graphics.LEFT); + g.setFont(Font.getDefaultFont()); + TankCanvas.drawHL(g, text, 8, getHeight() - 12 - ph, 0x9900, 0x99ffff, Graphics.BASELINE | Graphics.LEFT); + } + + /** + * Called when a key is pressed. + * @param key + */ + protected void keyPressed(int key) + { + int ga = getGameAction(key); + if ((ga == LEFT) || (key == '4')) + if (--index < 0) + index = 0; + if ((ga == RIGHT) || (key == '6')) + if (++index >= max) + index = max; + if ((ga == FIRE) || (key == '5')) + if (cl != null) + cl.commandAction(COMMAND_SELECT, this); + if (key == '0') + index = 0; + repaint(); + } + + protected void keyRepeated(int key) + { + int ga = getGameAction(key); + if ((ga == LEFT) || (key == '4')) + if ((index -= (int) add) < 0) + index = 0; + if ((ga == RIGHT) || (key == '6')) + if ((index += (int) add) >= max) + index = max; + add += 0.2; + repaint(); + } + + protected void keyReleased(int k) + { + add = 1; + } + + public int getSelectedValue() + { + return index; + } +} diff --git a/src/org/pabloid/tank/Settings.java b/src/org/pabloid/tank/Settings.java new file mode 100644 index 0000000..d79d4f0 --- /dev/null +++ b/src/org/pabloid/tank/Settings.java @@ -0,0 +1,118 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.pabloid.tank; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import javax.microedition.lcdui.Command; +import javax.microedition.lcdui.CommandListener; +import javax.microedition.lcdui.Displayable; +import javax.microedition.lcdui.Image; +import org.pabloid.io.RecordStoreInputStream; +import org.pabloid.io.RecordStoreOutputStream; +import org.pabloid.ui.PList; + +/** + * + * @author pabloid + */ +public class Settings extends PList implements CommandListener +{ + public static final String dbName = "Tank.settings"; + public int numElements; + private boolean[] elements; + private Image imTick = null, imCross = null; + + private void readSettings() + { + try + { + RecordStoreInputStream ris = new RecordStoreInputStream(dbName); + DataInputStream dis = new DataInputStream(ris); + elements = new boolean[numElements]; + for (int i = 0; i < numElements; i++) + elements[i] = dis.readBoolean(); + dis.close(); + } + catch (Exception e) + { + elements = new boolean[numElements]; + for (int i = 0; i < numElements; i++) + elements[i] = true; + saveSettings(); + //#ifdef DefaultConfiguration + e.printStackTrace(); + //#endif + } + catch (Throwable t) + { + t.printStackTrace(); + } + } + + public void saveSettings() + { + try + { + RecordStoreOutputStream ros = new RecordStoreOutputStream(dbName); + DataOutputStream dos = new DataOutputStream(ros); + for (int i = 0; i < numElements; i++) + dos.writeBoolean(elements[i]); + dos.close(); + } + catch (Throwable t) + { + t.printStackTrace(); + } + } + + public Settings(String items[]) + { + super(items); + try + { + numElements = items.length; + setTitle("Настройки"); + append("Назад"); + setCommandListener(this); + readSettings(); + imTick = Image.createImage("/res/tick.png"); + imCross = Image.createImage("/res/cross.png"); + for (int index = 0; index < numElements; index++) + set(index, getString(index), elements[index] ? imTick : imCross); + } + catch (Throwable t) + { + t.printStackTrace(); + } + } + + public void commandAction(Command c, Displayable d) + { + int index = getSelectedIndex(); + if (index >= numElements) + { + saveSettings(); + Tank.instance.d.setCurrent(Tank.instance.main); + return; + } + else + { + elements[index] = !elements[index]; + set(index, getString(index), elements[index] ? imTick : imCross); + } + } + + public boolean getSetting(int index) + { + return elements[index]; + } + + public void setSetting(int index, boolean value) + { + elements[index] = value; + set(index, getString(index), value ? imTick : imCross); + } +} diff --git a/src/org/pabloid/tank/Tank.java b/src/org/pabloid/tank/Tank.java new file mode 100644 index 0000000..b7c683b --- /dev/null +++ b/src/org/pabloid/tank/Tank.java @@ -0,0 +1,523 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.pabloid.tank; + +import java.io.IOException; +import java.util.Hashtable; +import javax.bluetooth.DeviceClass; +import javax.bluetooth.DiscoveryAgent; +import javax.bluetooth.DiscoveryListener; +import javax.bluetooth.L2CAPConnection; +import javax.bluetooth.L2CAPConnectionNotifier; +import javax.bluetooth.LocalDevice; +import javax.bluetooth.RemoteDevice; +import javax.bluetooth.ServiceRecord; +import javax.bluetooth.UUID; +import javax.microedition.io.Connector; +import javax.microedition.lcdui.Command; +import javax.microedition.lcdui.CommandListener; +import javax.microedition.lcdui.Display; +import javax.microedition.lcdui.Displayable; +import javax.microedition.lcdui.Form; +import javax.microedition.midlet.MIDlet; +import org.pabloid.io.IOUtils; +import org.pabloid.io.ResourceReader; +import org.pabloid.ui.PList; + +/** + * @author pabloid + */ +public class Tank extends MIDlet implements + //#ifndef NoBluetooth + CommandListener, DiscoveryListener, Runnable +//#else +//# CommandListener +//#endif +{ + public Display d; + public static Tank instance; + public PList main; + public PList shop; + private boolean bServer = true; + public static final int values[] = + { + 2000, 1750, 1500, 1250, 1000, 5000, 1000, 10000, 100500, 500, 1500, 30000, 20000 + }; + public Settings settings; + public TankCanvas c; + private Form help; + PList confirm, reset; + Command cmdBack; + private String url; + private Scale scale = new Scale(1); + private Loading loading; + //#ifndef NoBluetooth + PList devices; + PList multiplayerMenu; + private Hashtable htDevices = new Hashtable(); + public static L2CAPConnection con; + public static final String SERVICE_UUID = "1020304050d0708093a1b121d1e1f100"; + public static final UUID L2CAP_UUID = new UUID(0x100); + private DiscoveryAgent agent; + private LocalDevice local; + private boolean bBluetooth = true; + private Thread server; +//#endif + + public Tank() + { + instance = this; + d = Display.getDisplay(this); + loading = new Loading(18); + d.setCurrent(loading); + main = new PList(new String[] + { + "Заезд", "Магазин", + //#ifndef NoBluetooth + "Мультиплеер", + //#else + //# null, + //#endif + "Настройки", "Помощь", "Обнулить прогресс", "Выход" + }); + loading.next(); + shop = new PList(new String[] + { + "Зарядка(" + values[0] + ")", "Ракеты(" + values[1] + ")", "Скорость ракет(" + values[2] + ")", + "Управление(" + values[3] + ")", "Топливо(" + values[4] + ")", "Бомба(" + values[5] + ")", + "Щит(" + values[6] + ")", "Сброс скорости(" + values[7] + ")", "Шар Свиборга(" + values[8] + ")", + "Быстрая ракета(" + values[9] + ")", "Разрывная ракета(" + values[10] + ")", "Ракет одновременно(" + values[11] + ")", + "Мега-ракета(" + values[12] + ")", + "Назад" + }); + loading.next(); + reset = new PList(new String[] + { + "Зарядка", "Ракеты", "Скорость ракет", + "Управление", "Топливо", + "Щит", "Ракет одновременно", "Все", + "Назад" + }); + reset.setTitle("Сбросить"); + reset.setCommandListener(this); + loading.next(); + settings = new Settings(new String[] + { + "Режим ночи", "Вибрация" + }); + loading.next(); + help = new Form("Помощь"); + loading.next(); + c = new TankCanvas(); + loading.next(); + confirm = new PList(new String[] + { + "Нет", "Да" + }); + loading.next(); + cmdBack = new Command("Назад", Command.BACK, 0); + loading.next(); + //#ifndef NoBluetooth + devices = new PList("Bluetooth устройства", 0); + multiplayerMenu = new PList("Bluetooth мультиплеер", 0); + //#endif + main.setCommandListener(this); + loading.next(); + main.setTitle("Рекорд: " + c.maxScore); + loading.next(); + main.repaint(); + loading.next(); + shop.setCommandListener(this); + loading.next(); + confirm.setCommandListener(this); + loading.next(); + scale.setCommandListener(this); + loading.next(); + //#ifndef NoBluetooth + devices.setCommandListener(this); + devices.addCommand(cmdBack); + multiplayerMenu.setCommandListener(this); + multiplayerMenu.append("Клиент"); + multiplayerMenu.append("Сервер"); + multiplayerMenu.addCommand(cmdBack); + //#endif + try + { + ResourceReader r = new ResourceReader("/res/about.txt", "UTF-8"); + help.append(IOUtils.asString(r)); + r.close(); + } + catch (Throwable t) + { + t.printStackTrace(); + } + loading.next(); + help.setCommandListener(this); + loading.next(); + help.addCommand(new Command("ОК", Command.OK, 0)); + loading.next(); + d.setCurrent(main); + } + + public void startApp() + { + } + + public void pauseApp() + { + System.gc(); + } + + public void destroyApp(boolean unconditional) + { + notifyDestroyed(); + } + + public void commandAction(Command cmd, Displayable disp) + { + try + { + if (disp == help) + { + d.setCurrent(main); + return; + } + //#ifndef NoBluetooth + else if (bBluetooth && disp == multiplayerMenu && cmd == PList.SELECT_COMMAND) + { + int index = multiplayerMenu.getSelectedIndex(); + switch (index) + { + case 0: + devices.deleteAll(); + d.setCurrent(devices); + if (agent == null) + getLocalDevice(); + agent.startInquiry(DiscoveryAgent.GIAC, this); + devices.setTitle("Поиск устройств..."); + break; + case 1: + c.reset(); + d.setCurrent(c); + c.start(); + if (server == null) + { + server = new Thread(this); + server.start(); + } + break; + } + } + else if (disp == devices && cmd == PList.SELECT_COMMAND) + { + loading.start(); + d.setCurrent(loading); + String name = devices.getString(devices.getSelectedIndex()); + RemoteDevice remote = (RemoteDevice) htDevices.get(name); + agent.searchServices(null, new UUID[] + { + L2CAP_UUID, new UUID(SERVICE_UUID, false) + }, remote, this); + } + else if (disp == devices && cmd == cmdBack) + d.setCurrent(multiplayerMenu); + else if (disp == multiplayerMenu && cmd == cmdBack) + d.setCurrent(main); + //#endif + else if (cmd == PList.SELECT_COMMAND && disp == confirm) + { + if (confirm.getSelectedIndex() == 1) + { + switch (reset.getSelectedIndex()) + { + case 0: + c.fireSpeed = 1000; + break; + case 1: + c.maxMis = 2; + break; + case 2: + c.mis = 1; + break; + case 3: + c.controlSpeed = 1; + break; + case 4: + c.maxFuel = 100; + break; + case 5: + c.shield = 0; + break; + case 6: + c.nMissilesAtTime = 1; + break; + case 7: + c.resetGame(); + break; + } + c.save(); + } + d.setCurrent(main); + } + else if (cmd == PList.SELECT_COMMAND && disp == main) + switch (main.getSelectedIndex()) + { + case 0: + c.reset(); + c.start(); + d.setCurrent(c); + break; + case 1: + d.setCurrent(shop); + shop.setTitle("Денег: " + c.money); + shop.repaint(); + break; + case 2: +//#ifndef NoBluetooth + if (!bBluetooth) + { + multiplayerMenu.deleteAll(); + multiplayerMenu.append("Bluetooth не доступен"); + } + d.setCurrent(multiplayerMenu); + //#endif + break; + case 3: + d.setCurrent(settings); + break; + case 4: + d.setCurrent(help); + break; + case 5: + d.setCurrent(reset); + break; + case 6: + destroyApp(true); + break; + } + else if (cmd == PList.SELECT_COMMAND && disp == shop) + { + int index = shop.getSelectedIndex(); + if (index >= shop.size() - 1) + { + d.setCurrent(main); + main.repaint(); + shop.setTitle(""); + } + else if (c.money < values[index]) + shop.setTitle("Недостаточно денег"); + else + { + scale.setText(shop.getString(index)); + scale.setMax(c.money / values[index]); + d.setCurrent(scale); + } + new TitleRefreshThread().start(); + } + else if (cmd == Scale.COMMAND_SELECT && disp == scale) + { + int index = shop.getSelectedIndex(); + c.money -= scale.getSelectedValue() * values[index]; + switch (index) + { + case 0: + for (int i = 0; i < scale.getSelectedValue(); i++) + { + c.fireSpeed -= c.fireSpeed / 20; + if (c.fireSpeed < c.calcMinFiretime()) + { + c.fireSpeed = c.calcMinFiretime(); + c.money += values[0]; + shop.setTitle("Максимум"); + } + } + break; + case 1: + c.maxMis += scale.getSelectedValue(); + break; + case 2: + for (int i = 0; i < scale.getSelectedValue(); i++) + { + c.mis += 0.2; + if (c.mis > c.imMissile.getHeight()) + { + c.mis = c.imMissile.getHeight(); + c.money += values[2]; + shop.setTitle("Максимум"); + } + } + break; + case 3: + for (int i = 0; i < scale.getSelectedValue(); i++) + { + c.controlSpeed++; + if (c.controlSpeed > c.imTank.getHeight()) + { + c.controlSpeed = c.imMissile.getHeight(); + c.money += values[3]; + shop.setTitle("Максимум"); + } + } + break; + case 4: + for (int i = 0; i < scale.getSelectedValue(); i++) + c.maxFuel += (int) Math.ceil(5000.0 / c.maxFuel); + break; + case 5: + c.bombs += scale.getSelectedValue(); + break; + case 6: + c.shield += scale.getSelectedValue(); + break; + case 7: + c.speedReset += scale.getSelectedValue(); + break; + case 8: + c.swiborg += scale.getSelectedValue(); + break; + case 9: + c.nFastMissiles += scale.getSelectedValue(); + break; + case 10: + c.nExplosiveMissiles += scale.getSelectedValue(); + break; + case 11: + c.nMissilesAtTime += scale.getSelectedValue(); + if (c.nMissilesAtTime > 180) + { + c.money += (c.nMissilesAtTime - 180) * values[11]; + c.nMissilesAtTime = 180; + shop.setTitle("Максимум"); + } + break; + case 12: + c.nMultiExplosiveMissiles += scale.getSelectedValue(); + break; + + } + c.save(); + d.setCurrent(shop); + if (!shop.getTitle().startsWith("Денег:")) + new TitleRefreshThread().start(); + else + shop.setTitle("Денег: " + c.money); + } + else if (disp == reset && cmd == PList.SELECT_COMMAND) + if (reset.getSelectedIndex() == reset.size() - 1) + d.setCurrent(main); + else + { + String s = reset.getString(reset.getSelectedIndex()); + confirm.setTitle("Обнулить \"" + s + "\""); + confirm.setSelectedIndex(0, true); + d.setCurrent(confirm); + } + } + catch (Throwable t) + { + t.printStackTrace(); + } + } +//#ifndef NoBluetooth + + public boolean isServer() + { + return bServer; + } + + public void run() + { + try + { + if (local == null) + getLocalDevice(); + bServer = true; + local = LocalDevice.getLocalDevice(); + int mode = local.getDiscoverable(); + local.setDiscoverable(DiscoveryAgent.GIAC); + L2CAPConnectionNotifier serv = (L2CAPConnectionNotifier) Connector.open("btl2cap://localhost:" + SERVICE_UUID); + con = serv.acceptAndOpen(); + local.setDiscoverable(mode); + serv.close(); + } + catch (Throwable t) + { + t.printStackTrace(); + } + server = null; + } + + public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) + { + try + { + htDevices.put(btDevice.getFriendlyName(false), btDevice); + devices.append(btDevice.getFriendlyName(false)); + } + catch (IOException ex) + { + ex.printStackTrace(); + } + } + + public void servicesDiscovered(int transID, ServiceRecord[] servRecord) + { + ServiceRecord record = servRecord[0]; + url = record.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false); + } + + public void serviceSearchCompleted(int transID, int respCode) + { + bServer = false; + try + { + con = (L2CAPConnection) Connector.open(url); + } + catch (Throwable t) + { + t.printStackTrace(); + } + c.reset(); + c.start(); + loading.stop(); + d.setCurrent(c); + } + + public void inquiryCompleted(int discType) + { + devices.setTitle("Bluetooth-устройства"); + } + + private void getLocalDevice() + { + try + { + local = LocalDevice.getLocalDevice(); + agent = local.getDiscoveryAgent(); + bBluetooth = true; + } + catch (Throwable t) + { + bBluetooth = false; + } + } + //#endif + + private class TitleRefreshThread extends Thread + { + public void run() + { + try + { + sleep(2000); + } + catch (Throwable t) + { + t.printStackTrace(); + } + shop.setTitle("Денег: " + c.money); + } + } +} diff --git a/src/org/pabloid/tank/TankCanvas.java b/src/org/pabloid/tank/TankCanvas.java new file mode 100644 index 0000000..db17e1d --- /dev/null +++ b/src/org/pabloid/tank/TankCanvas.java @@ -0,0 +1,1491 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.pabloid.tank; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.Calendar; +import java.util.Random; +import java.util.TimeZone; +import java.util.Vector; +import javax.microedition.lcdui.Alert; +import javax.microedition.lcdui.Canvas; +import javax.microedition.lcdui.Font; +import javax.microedition.lcdui.Graphics; +import javax.microedition.lcdui.Image; +import javax.microedition.lcdui.game.Sprite; +import javax.microedition.rms.RecordStoreNotFoundException; +import org.pabloid.io.RecordStoreInputStream; +import org.pabloid.io.RecordStoreOutputStream; +import org.pabloid.ui.ImageTransformer; +import org.pabloid.ui.ImageUtils; + +/** + * @author pabloid + */ +public class TankCanvas extends Canvas implements Runnable, ImageTransformer +{ + public static final int DAY_LINE_COLOR = 0xFFFF99; + public static final int DAY_ROAD_COLOR = 0xCCCCCC; + public static final int DAY_SHIELD_COLOR = 0x00FFFF; + public static final int HL_BACKGROUND = 0xFF0000; + public static final int HL_FOREGROUND = 0xFFFF00; + public static final int NIGHT_LINE_COLOR = 0x999900; + public static final int NIGHT_ROAD_COLOR = 0x666666; + public static final int NIGHT_SHIELD_COLOR = 0x006666; + public static final int CAR_FRAMES = ImageLoader.CAR_FRAMES; + public static final int JIT_LIMIT = 20; + public static final int K_RIGHT = 0; + public static final int K_UP = 1; + public static final int K_LEFT = 2; + public static final int K_DOWN = 3; + public static final int K_FIRE = 4; + public static final int K_POUND = 5; + public static final int CAR_MAX = 20; + public static final int ORDINARY_MISSILE = 0; + public static final int FAST_MISSILE = 1; + public static final int EXPLOSIVE_MISSILE = 2; + public static final int MULTI_EXPLOSIVE_MISSILE = 3; + public static final double[] firespeedMultipliers = + { + 1, 0.5, 2, 4 + }; + private final int HOT_MAX; + public static final String oldDbName = "Tank.db"; + public static final String dbName = "Tank.game"; + public static final long SWIBORG_MAX_ACTIVATION_TIME = 30000; + Image imTank, imBTank, imMan, imCar, imMissile, imLive, imFuel, imBomb, imBoom, imSwiborg, imFastMissile; + Image buf; + Graphics g; + Sprite spTank, spBoom; + Car cars[] = new Car[CAR_MAX]; + Man men[] = new Man[CAR_MAX]; + boolean bRun; + boolean keys[] = + { + false, false, false, false, false, false + }; + static int w, h; + double ry; + double gy; + Image imGrass; + ImageLoader loader; + //--------------------------------- + boolean bCheat = false; + final int RW, RH; + double speed = 1; + Random rnd = new Random(); + Vector vMis = new Vector(); + long lastFire = 0; + int fuel = 100; + int lives = 2; + long ticks = 0; + double ly, fy, by; + int lx, fx, bx; + int btx, bty; + int btScore, btLives, btFuel, btBombs, btShield, btMaxFuel, btMaxMis; + boolean btBShield = false; + int score = 0; + int maxCars = 1; + int maxScore; + int level = 1; + int money; + int fps = 0; + private long exitTimeStamp; + boolean boom = false; + int shield; + boolean bShield; + private Thread thread; + private boolean bNight; + private boolean bVibrate; + private boolean bHot; + private int hotLevel; + private boolean bReady; + private boolean bJit = false; + private int jitCount = 0; + private boolean bGameOver; + private boolean bSpeedReseted = false; + private boolean bSwiborgActivated; + private long swiborgActivateTimestamp; + private int missileType; + //Покупные параметры + double mis = 1; + int controlSpeed = 1; + int fireSpeed = 1000; + int maxFuel = 100; + int maxMis = 2; + int bombs = 0; + int speedReset = 0; + int swiborg = 0; + int nFastMissiles = 0; + int nExplosiveMissiles = 0; + int nMultiExplosiveMissiles = 0; + int nMissilesAtTime = 1; + //------------------ + + public void start() + { + if (thread == null) + { + thread = new Thread(this); + thread.start(); + } + } + + public TankCanvas() + { + setFullScreenMode(true); + try + { + loader = new ImageLoader(); + } + catch (Throwable t) + { + t.printStackTrace(); + } + w = getWidth(); + h = getHeight(); + buf = Image.createImage(w, h); + g = buf.getGraphics(); + RH = h / 10; + RW = w / 40; + ry = -RH; + gy = 0; + reset(); + HOT_MAX = Math.min(h / imMissile.getHeight() * 10, maxMis * 10); + } + + public void reset() + { + resetSettings(); + for (int i = 0; i < CAR_MAX; i++) + { + cars[i].reset(); + men[i].reset(); + } + resetLive(); + resetFuel(); + resetBomb(); + bRun = true; + bGameOver = false; + read(); + lives = 2; + score = 0; + btMaxFuel = 0; + fuel = (maxFuel + btMaxFuel); + maxCars = 1; + speed = 1; + vMis.removeAllElements(); + spTank.setRefPixelPosition(w / 2, h - 50); + boom = false; + bShield = false; + btScore = 0; + btLives = 0; + btFuel = 0; + btShield = 0; + btBombs = 0; + btBShield = false; + btx = 0; + bty = 0; + bHot = false; + hotLevel = 0; + btMaxMis = 0; + bJit = false; + jitCount = 0; + bSwiborgActivated = false; + swiborgActivateTimestamp = 0; + missileType = ORDINARY_MISSILE; + } + + public void resetSettings() + { + boolean oldNight = bNight; + int hour = Calendar.getInstance(TimeZone.getDefault()).get(Calendar.HOUR_OF_DAY); + bNight = (Tank.instance.settings.getSetting(0) && (hour <= 6 || hour >= 19)); + bVibrate = Tank.instance.settings.getSetting(1); + if (imTank == null || oldNight != bNight) + try + { + imTank = loader.get(ImageLoader.ID_TANK); + if (bNight) + imTank = ImageUtils.transform(imTank, this); + imSwiborg = loader.get(ImageLoader.ID_SWIBORG); + if (bNight) + imSwiborg = ImageUtils.transform(imSwiborg, this); + //#ifndef NoBluetooth + imBTank = loader.get(ImageLoader.ID_BTANK); + if (bNight) + imBTank = ImageUtils.transform(imBTank, this); + //#endif + imMan = loader.get(ImageLoader.ID_MAN); + if (bNight) + imMan = ImageUtils.transform(imMan, this); + imCar = loader.get(ImageLoader.ID_CAR); + if (bNight) + imCar = ImageUtils.transform(imCar, this); + imMissile = loader.get(ImageLoader.ID_MIS); + if (bNight) + imMissile = ImageUtils.transform(imMissile, this); + imFastMissile = loader.get(ImageLoader.ID_FAST_MIS); + if (bNight) + imFastMissile = ImageUtils.transform(imFastMissile, this); + imLive = loader.get(ImageLoader.ID_LIVE); + if (bNight) + imLive = ImageUtils.transform(imLive, this); + imFuel = loader.get(ImageLoader.ID_FUEL); + if (bNight) + imFuel = ImageUtils.transform(imFuel, this); + imBomb = loader.get(ImageLoader.ID_BOMB); + if (bNight) + imBomb = ImageUtils.transform(imBomb, this); + imBoom = loader.get(ImageLoader.ID_BOOM); + + imGrass = Image.createImage(w / 5, 3 * h / 2); + Graphics gg = imGrass.getGraphics(); + for (int i = 0; i <= imGrass.getWidth(); i++) + for (int j = 0; j <= imGrass.getHeight(); j++) + { + int red = random(30, 150); + int green = random(red, 200); + int blue = random(0, red - 20); + if (bNight) + gg.setColor(red / 2, green / 2, blue / 2); + else + gg.setColor(red, green, blue); + gg.drawLine(i, j, i, j); + } + + spTank = new Sprite(imTank); + spBoom = new Sprite(imBoom, imBoom.getWidth() / 4, imBoom.getHeight()); + spBoom.defineReferencePixel(imBoom.getWidth() / 8, imBoom.getHeight() / 2); + spBoom.setFrame(0); + spTank.defineReferencePixel(imTank.getWidth() / 2, imTank.getHeight() / 2); + spTank.setRefPixelPosition(w / 2, h - 50); + for (int i = 0; i < CAR_MAX; i++) + { + men[i] = new Man(); + cars[i] = new Car(); + } + } + catch (Throwable e) + { + e.printStackTrace(); + } + } + + public void resetGame() + { + reset(); + mis = 1; + controlSpeed = 1; + fireSpeed = 1000; + maxFuel = 100; + maxMis = 2; + bombs = 0; + maxScore = 0; + level = 1; + money = 0; + shield = 30; + speedReset = 0; + swiborg = 0; + nFastMissiles = 0; + nExplosiveMissiles = 0; + nMultiExplosiveMissiles = 0; + nMissilesAtTime = 1; + Tank.instance.main.setTitle("Рекорд: " + maxScore); + save(); + } + + public void resume() + { + if (!bGameOver) + bRun = true; + } + + public void hideNotify() + { + bRun = false; + } + + void save() + { + try + { + RecordStoreOutputStream ros = new RecordStoreOutputStream(dbName); + DataOutputStream out = new DataOutputStream(ros); + out.writeInt(maxScore); + out.writeShort(fireSpeed); + out.writeByte(controlSpeed); + out.writeInt(money); + out.writeInt(maxFuel); + out.writeInt(maxMis); + out.writeDouble(mis); + out.writeInt(bombs); + out.writeInt(shield); + out.writeShort(speedReset); + out.writeByte(swiborg); + out.writeInt(nFastMissiles); + out.writeInt(nExplosiveMissiles); + out.writeInt(nMissilesAtTime); + out.writeInt(nMultiExplosiveMissiles); + out.close(); + } + catch (Throwable t) + { + t.printStackTrace(); + } + } + + void read() + { + try + { + RecordStoreInputStream ris = new RecordStoreInputStream(dbName); + DataInputStream in = new DataInputStream(ris); + maxScore = in.readInt(); + fireSpeed = in.readShort(); + controlSpeed = in.readByte(); + money = in.readInt(); + maxFuel = in.readInt(); + maxMis = in.readInt(); + mis = in.readDouble(); + bombs = in.readInt(); + shield = in.readInt(); + speedReset = in.readShort(); + swiborg = in.readByte(); + nFastMissiles = in.readInt(); + nExplosiveMissiles = in.readInt(); + nMissilesAtTime = in.readInt(); + nMultiExplosiveMissiles = in.readInt(); + in.close(); + } + catch (RecordStoreNotFoundException rnfe) + { + save(); + } + catch (IOException t) + { + nFastMissiles = 0; + nExplosiveMissiles = 0; + nMissilesAtTime = 1; + nMultiExplosiveMissiles = 0; + save(); + } + catch (Throwable t) + { + t.printStackTrace(); + } + } + + void resetLive() + { + lx = random(w / 5, w - w / 5 - 8); + ly = random(-5000, -3000); + } + + void resetBomb() + { + bx = random(w / 5, w - w / 5 - 8); + by = random(-25000, -15000); + } + + void resetFuel() + { + fx = random(w / 5, w - w / 5 - 8); + fy = random(-(maxFuel + btMaxFuel) * 10, -(maxFuel + btMaxFuel) * 7); + } + + void addFuel() + { + fuel += 50; + if ((fuel + btFuel) > (maxFuel + btMaxFuel)) + fuel = maxFuel; + } + + int random(int a, int b) + { + int r = Math.abs(rnd.nextInt()); + int d = b - a; + r %= d; + r += a; + return r; + } + + public void paint(Graphics g) + { + if (bReady) + { + g.setFont(Font.getDefaultFont()); + int x = 0, y = 0; + if (bJit) + { + if (jitCount++ > JIT_LIMIT) + { + jitCount = 0; + bJit = false; + } + int spd = (int) speed; + x = random(-spd, spd); + y = random(-spd, spd); + if (!bNight) + g.setColor(DAY_ROAD_COLOR); + else + g.setColor(NIGHT_ROAD_COLOR); + g.fillRect(0, 0, w, h); + } + g.drawImage(buf, x, y, 20); + if (!bRun && !bGameOver) + { + drawHL(g, "Пауза", w / 2, h / 2 - 2, HL_BACKGROUND, HL_FOREGROUND, Graphics.HCENTER | Graphics.BASELINE); + drawHL(g, "Нажмите *", w / 2, h / 2 + 2, HL_BACKGROUND, HL_FOREGROUND, Graphics.HCENTER | Graphics.TOP); + } + else if (bGameOver) + { + g.setFont(Font.getFont(0, Font.STYLE_BOLD, Font.SIZE_LARGE)); + drawHL(g, "ИГРА ОКОНЧЕНА", w / 2, h / 4, HL_BACKGROUND, HL_FOREGROUND, Graphics.BASELINE | Graphics.HCENTER); + g.setFont(Font.getDefaultFont()); + drawHL(g, "Очки: " + (score + btScore), w / 2, h / 2, HL_BACKGROUND, HL_FOREGROUND, Graphics.BASELINE | Graphics.HCENTER); + drawHL(g, "Рекорд: " + maxScore, w / 2, h / 2 + 3, HL_BACKGROUND, HL_FOREGROUND, Graphics.TOP | Graphics.HCENTER); + drawHL(g, "1 - Меню", w / 2, h / 2 + 5 + g.getFont().getHeight(), HL_BACKGROUND, HL_FOREGROUND, Graphics.TOP | Graphics.HCENTER); + //#ifndef NoBluetooth + if (Tank.con == null) + //#endif + drawHL(g, "2 - Рестарт", w / 2, h / 2 + 5 + g.getFont().getHeight() * 2, HL_BACKGROUND, HL_FOREGROUND, Graphics.TOP | Graphics.HCENTER); + } + + + bReady = false; + } + } + + void moveRoad() + { + gy += speed; + if (gy >= 0) + gy = -h; + ry += speed; + if (ry > h / 2) + ry = 0; + ly += speed; + if (ly > h) + resetLive(); + fy += speed; + if (fy > h) + resetFuel(); + by += speed; + if (by > h) + resetBomb(); + //#ifndef NoBluetooth + if (Tank.instance.isServer() || Tank.con == null) + //#endif + for (int i = 0; i < maxCars; i++) + { + cars[i].move(); + men[i].move(); + } + if (boom) + spBoom.setRefPixelPosition(spBoom.getRefPixelX(), (int) (spBoom.getRefPixelY() + speed)); + } + + void moveMis(int i) + { + Missile m = (Missile) vMis.elementAt(i); + m.move(); + if (m.isOut()) + vMis.removeElementAt(i); + } + + void drawBackground() + { + if (!bNight) + g.setColor(DAY_ROAD_COLOR); + else + g.setColor(NIGHT_ROAD_COLOR); + g.fillRect(0, 0, w, h); + + g.drawImage(imGrass, 0, (int) gy, 0); + g.drawImage(imGrass, w - w / 5, (int) gy, 0); + g.drawImage(imGrass, 0, (int) gy + h, 0); + g.drawImage(imGrass, w - w / 5, (int) gy + h, 0); + } + + void processKeys() + { + if (keys[K_LEFT] && (spTank.getRefPixelX() > w / 5 + imTank.getWidth() / 2)) + spTank.move(-controlSpeed, 0); + if (keys[K_UP] && (spTank.getRefPixelY() > imTank.getHeight() / 2)) + spTank.move(0, -controlSpeed); + if (keys[K_DOWN] && (spTank.getRefPixelY() < h - imTank.getHeight() / 2)) + spTank.move(0, controlSpeed); + if (keys[K_RIGHT] && (spTank.getRefPixelX() < w - w / 5 - imTank.getWidth() / 2)) + spTank.move(controlSpeed, 0); + if (keys[K_FIRE] && !bHot && vMis.size() < (maxMis + btMaxMis) * nMissilesAtTime && System.currentTimeMillis() - lastFire > fireSpeed * firespeedMultipliers[missileType]) + { + int oneMissileWidth = Math.max(imTank.getWidth() / nMissilesAtTime, imMissile.getWidth()); + int offset = oneMissileWidth / 2; + boolean addHot = false; + int startOffset = spTank.getRefPixelX() - (oneMissileWidth * nMissilesAtTime) / 2; + for (int i = 0; i < nMissilesAtTime; i++) + { + Missile m = null; + int currOffset = i * oneMissileWidth + offset; + switch (missileType) + { + case ORDINARY_MISSILE: + default: + m = new Missile(imMissile, startOffset + currOffset, spTank.getY() - imMissile.getHeight(), mis, ORDINARY_MISSILE); + break; + case FAST_MISSILE: + if (nFastMissiles > 0) + { + m = new Missile(imFastMissile, spTank.getRefPixelX() - imMissile.getWidth() / 2, spTank.getY() - imFastMissile.getHeight(), mis * 2, FAST_MISSILE); + nFastMissiles--; + } + break; + case EXPLOSIVE_MISSILE: + if (nExplosiveMissiles > 0) + { + m = new Missile(imMissile, spTank.getRefPixelX() - imMissile.getWidth() / 2, spTank.getY() - imMissile.getHeight(), mis, EXPLOSIVE_MISSILE); + nExplosiveMissiles--; + } + break; + case MULTI_EXPLOSIVE_MISSILE: + if (nMultiExplosiveMissiles > 0) + { + m = new Missile(imMissile, spTank.getRefPixelX() - imMissile.getWidth() / 2, spTank.getY() - imMissile.getHeight(), mis, MULTI_EXPLOSIVE_MISSILE); + m.multiCount = nMissilesAtTime; + nMultiExplosiveMissiles--; + } + break; + + } + if (m != null) + { + vMis.addElement(m); + lastFire = System.currentTimeMillis(); + addHot = true; + } + if (missileType != ORDINARY_MISSILE) + break; + } + if (addHot) + { + hotLevel += 10; + if (hotLevel >= HOT_MAX) + { + bHot = true; + hotLevel = HOT_MAX; + } + } + } + if (keys[K_POUND] && bombs != 0) + { + bombs--; + bJit = true; + jitCount = -10; + for (int i = 0; i < maxCars; i++) + { + if (cars[i].getFrame() < CAR_FRAMES) + cars[i].setFrame(cars[i].getFrame() + CAR_FRAMES); + men[i].setFrame(1); + score += 20; + } + keys[K_POUND] = false; + } + } + + void checkCollisions() + { + for (int i = 0; i < maxCars; i++) + if (bSwiborgActivated) + { + cars[i].kill(); + men[i].setFrame(1); + } + else + { + for (int j = 0; j < maxCars; j++) + { + if (men[j].getFrame() == 0 && cars[i].collidesWith(men[j], false)) + men[j].setFrame(1); + if (i != j && cars[i].collidesWith(cars[j], false)) + { + if (cars[j].getFrame() < CAR_FRAMES) + cars[j].setFrame(cars[j].getFrame() + CAR_FRAMES); + if (cars[i].getFrame() < CAR_FRAMES) + cars[i].setFrame(cars[i].getFrame() + CAR_FRAMES); + } + if (i != j && men[i].collidesWith(men[j], false)) + { + if (men[j].getFrame() == 0) + men[j].setFrame(1); + if (men[i].getFrame() == 0) + men[i].setFrame(1); + } + } + if ((spTank.collidesWith(men[i], false) && men[i].getFrame() == 0)) + { + men[i].setFrame(1); + score += 10; + } + if (spTank.collidesWith(cars[i], false) && cars[i].getFrame() < CAR_FRAMES) + { + cars[i].setFrame(CAR_FRAMES + cars[i].getFrame()); + if (!bShield) + { + lives--; + bJit = true; + jitCount = 0; + } + else + score += 15; + if (bVibrate) + Tank.instance.d.vibrate(500); + } + //#ifndef NoBluetooth + if (Tank.con != null) + { + if (men[i].collidesWith(imBTank, btx, bty, false) && men[i].getFrame() == 0) + { + men[i].setFrame(1); + score += 10; + } + if (cars[i].collidesWith(imBTank, btx, bty, false) && cars[i].getFrame() < CAR_FRAMES) + { + cars[i].setFrame(CAR_FRAMES + cars[i].getFrame()); + if (!btBShield && Tank.instance.isServer()) + lives--; + else + score += 15; + if (!bShield) + { + lives--; + bJit = true; + } + if (bVibrate) + Tank.instance.d.vibrate(500); + } + } + //#endif + for (int j = 0; j < vMis.size(); j++) + { + Missile m = (Missile) vMis.elementAt(j); + if ((cars[i].collidesWith(m.getImage(), m.getX(), m.getY(), false) && cars[i].getFrame() < CAR_FRAMES)) + { + if (!(m.getType() == FAST_MISSILE && cars[i].isPolice())) + { + if (cars[i].getRefPixelX() < w / 2) + score += 15; + score += 30; + cars[i].kill(); + } + vMis.removeElementAt(j); + if (m.getType() == EXPLOSIVE_MISSILE || m.getType() == MULTI_EXPLOSIVE_MISSILE) + { + int offset = 360 / (nMissilesAtTime * 2); + if (offset <= 0) + offset = 1; + for (int k = 0; k < nMissilesAtTime * 2; k++) + { + int type; + if (m.getType() == EXPLOSIVE_MISSILE || m.multiCount == 0) + type = FAST_MISSILE; + else + { + m.multiCount--; + type = MULTI_EXPLOSIVE_MISSILE; + } + Missile missile = new Missile(imFastMissile, m.getX(), m.getY(), mis, type, k * offset); + vMis.addElement(missile); + } + } + if (bVibrate) + Tank.instance.d.vibrate(100); + } + } + } + if (spTank.collidesWith(imFuel, fx, (int) fy, false)) + { + score += 50; + addFuel(); + resetFuel(); + } + if (spTank.collidesWith(imLive, lx, (int) ly, false)) + { + score += 75; + lives++; + resetLive(); + } + if (spTank.collidesWith(imBomb, bx, (int) by, false)) + { + score += 150; + bombs++; + resetBomb(); + } + } + + public void run() + { + int i = 0; + long st; + st = System.currentTimeMillis(); + while (true) + try + { + long start = System.currentTimeMillis(); + i++; + if (System.currentTimeMillis() - st >= 1000) + { + fps = i; + i = 0; + st = System.currentTimeMillis(); + } + if (bRun) + { + //#ifndef NoBluetooth + writeState(); + readState(); + //#endif + tick(); + ticks++; + hotLevel--; + if (hotLevel <= HOT_MAX / 2) + bHot = false; + if (hotLevel < 0) + hotLevel = 0; + if ((ticks % 4) == 0 && boom) + { + int frame = spBoom.getFrame() + 1; + if (frame >= 4) + boom = false; + else + spBoom.setFrame(frame); + } + if (i == 0 && bShield) + shield--; + if ((shield + btShield) <= 0) + { + bShield = false; + shield = 0; + } + if ((ticks % 20) == 0) + { + fuel--; + score += Math.floor(speed); + } + if ((ticks % 400) == 0) + { + if (maxCars < CAR_MAX) + { + cars[maxCars].reset(); + men[maxCars].reset(); + maxCars++; + } + //#ifndef NoBluetooth + if (Tank.instance.isServer()) + //#endif + speed += 0.5; + } + if (bSwiborgActivated) + if (System.currentTimeMillis() - swiborgActivateTimestamp >= SWIBORG_MAX_ACTIVATION_TIME) + bSwiborgActivated = false; + } + bReady = true; + repaint(); + serviceRepaints(); + long duration = System.currentTimeMillis() - start; + if (duration < 25) + Thread.sleep(25 - duration); + } + catch (Throwable t) + { + t.printStackTrace(); + alert(t); + } + } + + void tick() throws Throwable + { + drawBackground(); + g.setFont(Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL)); + //--------------------------------------------- + moveRoad(); + processKeys(); + checkCollisions(); + //----------------------------------------------- + if (!bNight) + g.setColor(DAY_LINE_COLOR); + else + g.setColor(NIGHT_LINE_COLOR); + g.fillRect((w - RW) / 2, (int) ry, RW, RH); + g.fillRect((w - RW) / 2, (int) (ry + h / 2), RW, RH); + g.fillRect((w - RW) / 2, (int) (ry - h / 2), RW, RH); + g.drawImage(imFuel, fx, (int) fy, 20); + g.drawImage(imLive, lx, (int) ly, 20); + for (int i = 0; i < maxCars; i++) + men[i].paint(g); + for (int i = 0; i < maxCars; i++) + cars[i].paint(g); + for (int i = 0; i < vMis.size(); i++) + { + Missile m = (Missile) vMis.elementAt(i); + moveMis(i); + g.drawImage(m.getImage(), m.getX(), m.getY(), 20); + } + int charHeight = g.getFont().getHeight(); + int red, green; + int fh = (h - 10 - 3 * charHeight) * (fuel + btFuel) / (maxFuel + btMaxFuel); + if ((fuel + btFuel) > (maxFuel + btMaxFuel) / 2) + { + red = 256 - 512 * ((fuel + btFuel) - (maxFuel + btMaxFuel) / 2) / (maxFuel + btMaxFuel); + green = 255; + if (red > 255) + red = 255; + if (red < 0) + red = 0; + } + else if ((fuel + btFuel) < (maxFuel + btMaxFuel) / 2) + { + green = 512 * (fuel + btFuel) / (maxFuel + btMaxFuel); + red = 255; + if (green > 255) + green = 255; + if (green < 0) + green = 0; + } + else + { + green = 255; + red = 255; + } + g.setColor(red, green, 0); + g.fillRect(w - 15, h - 5 - fh, 10, fh); + int hh = (h - charHeight * 5 - 15) * (hotLevel) / (HOT_MAX); + if (hotLevel < HOT_MAX / 2) + { + red = 512 * (hotLevel) / HOT_MAX; + green = 255; + if (red > 255) + red = 255; + if (red < 0) + red = 0; + } + else if (hotLevel > HOT_MAX / 2) + { + green = 256 - 512 * (hotLevel - HOT_MAX / 2) / HOT_MAX; + red = 255; + if (green > 255) + green = 255; + if (green < 0) + green = 0; + } + else + { + green = 255; + red = 255; + } + g.setColor(red, green, 0); + g.fillRect(3, h - 5 - hh, 10, hh); + g.drawImage(imFuel, w - 13, h - 3 - fh, 20); + drawHL(g, "" + (score + btScore), 2, 2, HL_BACKGROUND, HL_FOREGROUND, 20); + g.drawImage(imLive, 2, 6 + charHeight, 20); + drawHL(g, "" + (lives + btLives), 12, 4 + charHeight, HL_BACKGROUND, HL_FOREGROUND, 20); + g.setColor(DAY_LINE_COLOR); + g.fillRect(1, 3 + charHeight * 2, imFuel.getWidth() + 2, imFuel.getHeight() + 2); + g.drawImage(imFuel, 2, 4 + charHeight * 2, 20); + drawHL(g, "" + (fuel + btFuel), 12, 4 + charHeight * 2, NIGHT_LINE_COLOR, DAY_LINE_COLOR, 20); + g.drawImage(imBomb, 2, 4 + charHeight * 3, 20); + drawHL(g, "" + bombs, 12, 4 + charHeight * 3, HL_BACKGROUND, HL_FOREGROUND, 20); + g.setColor(DAY_SHIELD_COLOR); + g.fillArc(2, 6 + charHeight * 4, 8, 8, 0, 360); + drawHL(g, "" + (shield + btShield), 12, 4 + charHeight * 4, NIGHT_SHIELD_COLOR, DAY_SHIELD_COLOR, 20); + switch (missileType) + { + case ORDINARY_MISSILE: + default: + g.drawImage(imMissile, w - 2, 2, Graphics.TOP | Graphics.RIGHT); + break; + case FAST_MISSILE: + g.drawImage(imFastMissile, w - 2, 6, Graphics.TOP | Graphics.RIGHT); + drawHL(g, "" + nFastMissiles, w - 4 - imFastMissile.getWidth(), 2, HL_BACKGROUND, HL_FOREGROUND, Graphics.TOP | Graphics.RIGHT); + break; + case EXPLOSIVE_MISSILE: + g.drawImage(imMissile, w - 2, 2, Graphics.TOP | Graphics.RIGHT); + g.drawImage(imFastMissile, w - 2, 6, Graphics.TOP | Graphics.RIGHT); + drawHL(g, "" + nExplosiveMissiles, w - 4 - imMissile.getWidth(), 2, HL_BACKGROUND, HL_FOREGROUND, Graphics.TOP | Graphics.RIGHT); + break; + case MULTI_EXPLOSIVE_MISSILE: + g.drawImage(imMissile, w - 2, 2, Graphics.TOP | Graphics.RIGHT); + g.drawImage(imFastMissile, w - 2, 7, Graphics.TOP | Graphics.RIGHT); + g.drawImage(imFastMissile, w - 2, 1, Graphics.TOP | Graphics.RIGHT); + drawHL(g, "" + nMultiExplosiveMissiles, w - 4 - imMissile.getWidth(), 2, HL_BACKGROUND, HL_FOREGROUND, Graphics.TOP | Graphics.RIGHT); + break; + } + drawHL(g, "SR " + speedReset, w - 2, 4 + charHeight, HL_BACKGROUND, HL_FOREGROUND, Graphics.RIGHT | Graphics.TOP); + if (!bSwiborgActivated || (ticks % 40 < 20)) + drawHL(g, "SW " + swiborg, w - 2, 4 + charHeight * 2, HL_BACKGROUND, HL_FOREGROUND, Graphics.RIGHT | Graphics.TOP); + //#ifdef DefaultConfiguration + drawHL(g, "" + fps, w - 4, h - 4, HL_BACKGROUND, HL_FOREGROUND, Graphics.RIGHT | Graphics.BASELINE); + //#endif + if (boom) + spBoom.paint(g); + if (bShield) + { + if (bNight) + g.setColor(NIGHT_SHIELD_COLOR); + else + g.setColor(DAY_SHIELD_COLOR); + int wd = (int) (imTank.getWidth() * 1.5); + int ht = (int) (imTank.getHeight() * 1.5); + g.drawArc(spTank.getRefPixelX() - wd / 2, spTank.getRefPixelY() - ht / 2, wd - 1, ht - 1, 0, 360); + } + //#ifndef NoBluetooth + if (Tank.con != null) + { + if (btBShield) + { + if (bNight) + g.setColor(NIGHT_SHIELD_COLOR); + else + g.setColor(DAY_SHIELD_COLOR); + int wd = (int) (imBTank.getWidth() * 1.5); + int ht = (int) (imBTank.getHeight() * 1.5); + g.drawArc(btx - wd / 2, bty - ht / 2, wd - 1, ht - 1, 0, 360); + } + g.drawImage(imBTank, btx, bty, Graphics.HCENTER | Graphics.VCENTER); + } + //#endif + spTank.paint(g); + if (bSwiborgActivated) + g.drawImage(imSwiborg, spTank.getRefPixelX(), spTank.getRefPixelY(), Graphics.HCENTER | Graphics.VCENTER); + //-------------------------------------------------- + if ((fuel + btFuel) <= 0) + { + lives--; + fuel = maxFuel; + } + if ((lives + btLives) <= 0) + gameOver(); + } + + void gameOver() + { + bRun = false; + bGameOver = true; + money += (score + btScore); + if ((score + btScore) > maxScore) + maxScore = score + btScore; + try + { + save(); + //#ifndef NoBluetooth + if (Tank.con != null) + { + Tank.con.close(); + Tank.con = null; + } + //#endif + } + catch (Throwable t) + { + t.printStackTrace(); + } + Tank.instance.main.setTitle("Рекорд: " + maxScore); + repaint(); + serviceRepaints(); + } + + public static void drawHL(Graphics g, String text, int x, int y, int bg, int fg, int a) + { + int color = g.getColor(); + g.setColor(bg); + g.drawString(text, x - 1, y - 1, a); + g.drawString(text, x, y - 1, a); + g.drawString(text, x + 1, y - 1, a); + g.drawString(text, x - 1, y, a); + g.drawString(text, x + 1, y, a); + g.drawString(text, x - 1, y + 1, a); + g.drawString(text, x, y + 1, a); + g.drawString(text, x + 1, y + 1, a); + g.setColor(fg); + g.drawString(text, x, y, a); + g.setColor(color); + } + + public void keyPressed(int key) + { + if (key == '1' || key == '3') + if (bCheat) + money += 20000; + else + bCheat = true; + + if (!bGameOver) + { + int ga = getGameAction(key); + if ((ga == LEFT) || (key == '4')) + keys[K_LEFT] = true; + if ((ga == UP) || (key == '2')) + keys[K_UP] = true; + if ((ga == DOWN) || (key == '8')) + keys[K_DOWN] = true; + if ((ga == RIGHT) || (key == '6')) + keys[K_RIGHT] = true; + if ((ga == FIRE) || (key == '5')) + keys[K_FIRE] = true; + if (key == '#') + keys[K_POUND] = true; + if (key == '*') + { + exitTimeStamp = System.currentTimeMillis(); + if (!bRun) + resume(); + else + { + bRun = false; + repaint(); + serviceRepaints(); + } + } + if (bRun) + { + if (key == '0') + bShield = !bShield; + if (key == '9' && speedReset > 0) + { + speedReset--; + speed = 1; + maxCars = 1; + bSpeedReseted = true; + } + if (key == '7' && !bSwiborgActivated && swiborg > 0) + { + swiborg--; + bSwiborgActivated = true; + swiborgActivateTimestamp = System.currentTimeMillis(); + } + if (key == '1') + if (missileType == ORDINARY_MISSILE) + missileType = FAST_MISSILE; + else if (missileType == FAST_MISSILE) + missileType = EXPLOSIVE_MISSILE; + else if (missileType == EXPLOSIVE_MISSILE) + missileType = MULTI_EXPLOSIVE_MISSILE; + else if (missileType == MULTI_EXPLOSIVE_MISSILE) + missileType = ORDINARY_MISSILE; + } + } + else + switch (key) + { + case '2': + //#ifndef NoBluetooth + if (Tank.con == null) + //#endif + { + reset(); + showNotify(); + } + break; + case '1': + Tank.instance.d.setCurrent(Tank.instance.main); + break; + } + } + + public void keyReleased(int key) + { + bCheat = false; + int ga = getGameAction(key); + if ((ga == LEFT) || (key == '4')) + keys[K_LEFT] = false; + if ((ga == UP) || (key == '2')) + keys[K_UP] = false; + if ((ga == DOWN) || (key == '8')) + keys[K_DOWN] = false; + if ((ga == RIGHT) || (key == '6')) + keys[K_RIGHT] = false; + if ((ga == FIRE) || (key == '5')) + keys[K_FIRE] = false; + if (key == '#') + keys[K_POUND] = false; + if (key == '*' && System.currentTimeMillis() - exitTimeStamp > 750) + { + gameOver(); + Tank.instance.d.setCurrent(Tank.instance.main); + } + } + + public void keyRepeated(int key) + { + if (key == '*' && System.currentTimeMillis() - exitTimeStamp > 750) + { + gameOver(); + Tank.instance.d.setCurrent(Tank.instance.main); + } + } + + public int calcMinFiretime() + { + int hh = imMissile.getHeight(); + double spd = mis * 0.025; + return (int) (hh / spd); + } + + public int getColor(Image orig, int x, int y, int color) + { + int alpha = (color >> 24) & 0xff; + int red = (color >> 16) & 0xff; + int green = (color >> 8) & 0xff; + int blue = color & 0xff; + red /= 2; + green /= 2; + blue /= 2; + return (alpha << 24) | (red << 16) | (green << 8) | blue; + } + //#ifndef NoBluetooth + + private void readState() + { + if (Tank.con != null) + try + { + // if (Tank.con.ready()) + { + byte[] data = new byte[Tank.con.getReceiveMTU()]; + Tank.con.receive(data); + DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data)); + int wd = dis.readShort(); + int ht = dis.readShort(); + double wc = (double) w / wd; + double hc = (double) h / ht; + btx = (int) (dis.readShort() * wc); + bty = (int) (dis.readShort() * hc); + btScore = dis.readInt(); + btLives = dis.readByte(); + btFuel = dis.readShort(); + btMaxFuel = dis.readShort(); + btShield = dis.readInt(); + btBShield = dis.readBoolean(); + if (!Tank.instance.isServer()) + { + maxCars = dis.readByte(); + for (int i = 0; i < maxCars; i++) + { + int x = (int) (dis.readShort() * wc); + int y = (int) (dis.readShort() * hc); + int frame = dis.readByte(); + boolean dir = x < w * wc / 2; + cars[i].setRefPixelPosition(x, y); + cars[i].setFrame(frame); + cars[i].setTransform(dir ? Sprite.TRANS_ROT180 : Sprite.TRANS_NONE); + x = (int) (dis.readShort() * wc); + y = (int) (dis.readShort() * hc); + frame = dis.readByte(); + dir = x < w * wc / 2; + men[i].setRefPixelPosition(x, y); + men[i].setFrame(frame); + men[i].setTransform(dir ? Sprite.TRANS_ROT180 : Sprite.TRANS_NONE); + } + speed = dis.readFloat(); + } + else + { + boolean speedReseted = dis.readBoolean(); + if (speedReseted) + { + speed = 1; + maxCars = 1; + } + for (int i = 0; i < maxCars; i++) + { + boolean killed = dis.readBoolean(); + if (killed && cars[i].getRefPixelY() >= 0) + cars[i].kill(); + } + } + btMaxMis = dis.readShort(); + if (dis.readBoolean()) + { + double spd = dis.readFloat(); + Missile m = new Missile(imMissile, btx - imMissile.getWidth() / 2, bty - imBTank.getHeight() / 2, spd, ORDINARY_MISSILE); + vMis.addElement(m); + } + dis.close(); + } + } + catch (Throwable t) + { + t.printStackTrace(); + gameOver(); + } + } + + private void writeState() + { + if (Tank.con != null) + try + { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(bos); + dos.writeShort(w); + dos.writeShort(h); + dos.writeShort(spTank.getRefPixelX()); + dos.writeShort(spTank.getRefPixelY()); + dos.writeInt(score); + dos.writeByte(lives); + dos.writeShort(fuel); + dos.writeShort(maxFuel); + dos.writeInt(shield); + dos.writeBoolean(bShield); + if (Tank.instance.isServer()) + { + dos.writeByte(maxCars); + for (int i = 0; i < maxCars; i++) + { + dos.writeShort(cars[i].getRefPixelX()); + dos.writeShort(cars[i].getRefPixelY()); + dos.writeByte(cars[i].getFrame()); + dos.writeShort(men[i].getRefPixelX()); + dos.writeShort(men[i].getRefPixelY()); + dos.writeByte(men[i].getFrame()); + } + dos.writeFloat((float) speed); + } + else + { + dos.writeBoolean(bSpeedReseted); + bSpeedReseted = false; + for (int i = 0; i < maxCars; i++) + dos.writeBoolean(cars[i].getFrame() >= CAR_FRAMES); + } + dos.writeShort(maxMis); + boolean fire = keys[K_FIRE] && vMis.size() < (maxMis + btMaxMis) && System.currentTimeMillis() - lastFire > fireSpeed && !bHot; + dos.writeBoolean(fire); + if (fire) + dos.writeFloat((float) mis); + Tank.con.send(bos.toByteArray()); + } + catch (Throwable t) + { + t.printStackTrace(); + gameOver(); + } + } + //#endif + + private void alert(Throwable t) + { + Alert a = new Alert("Ошибка", "Ошибка: " + t + "\nСообщите разработчику", null, null); + a.setTimeout(5000); + Tank.instance.d.setCurrent(a); + } + + class Man extends Sprite + { + private double y; + private double x; + private double cf; + private boolean dir; + + Man() + { + super(imMan, imMan.getWidth() / 2, imMan.getHeight()); + defineReferencePixel(imMan.getWidth() / 4, imMan.getHeight() / 2); + reset(); + } + + void reset() + { + y = -random(20, 120); + x = random(w / 5, w - w / 5); + cf = random(100, 200) / 100.0; + setFrame(0); + dir = getRefPixelX() < w / 2; + if (dir) + setTransform(Sprite.TRANS_ROT180); + else + setTransform(Sprite.TRANS_NONE); + move(); + } + + public int getRefPixelY() + { + return (int) y; + } + + public int getRefPixelX() + { + return (int) x; + } + + void move() + { + if (getFrame() == 0) + { + if (dir) + y += speed * cf; + else + y += speed / cf; + if (fps >= 15) + for (int i = 0; i < maxCars; i++) + { + boolean inWidth = Math.abs(x - cars[i].getRefPixelX()) <= imCar.getWidth() / CAR_FRAMES; + boolean inHeight = Math.abs(y - cars[i].getRefPixelY()) <= imCar.getHeight(); + if (inWidth && inHeight) + if (x < cars[i].getRefPixelX()) + x -= cf; + else + x += cf; + if (men[i] != this) + { + + inWidth = Math.abs(x - men[i].getRefPixelX()) <= imMan.getWidth(); + inHeight = Math.abs(y - men[i].getRefPixelY()) <= imMan.getHeight() * 2; + if (inWidth && inHeight) + if (x < men[i].getRefPixelX()) + x -= cf; + else + x += cf; + } + } + boolean inWidth = Math.abs(x - spTank.getRefPixelX()) <= imTank.getWidth(); + boolean inHeight = Math.abs(y - spTank.getRefPixelY()) <= imTank.getHeight() * 2; + if (inWidth && inHeight) + if (x < spTank.getRefPixelX()) + x -= cf; + else + x += cf; + if (x <= w / 5) + x = w / 5; + if (x >= w - w / 5) + x = w - w / 5; + } + else + y += speed; + if (y > h + 10) + reset(); + setRefPixelPosition(getRefPixelX(), getRefPixelY()); + } + } + + class Car extends Sprite + { + private double y; + private double x; + private double cf; + private boolean dir; + + Car() + { + super(imCar, imCar.getWidth() / CAR_FRAMES, imCar.getHeight() / 2); + defineReferencePixel(imCar.getWidth() / CAR_FRAMES / 2, imCar.getHeight() / 4); + reset(); + } + + private boolean isPolice() + { + boolean b = getFrame() == CAR_FRAMES - 1; + return b; + } + + void reset() + { + y = -random(20, 120); + x = random(w / 5, w - w / 5); + cf = random(100, 300) / 100.0; + setFrame(random(0, CAR_FRAMES)); + dir = getRefPixelX() < w / 2; + if (dir) + setTransform(Sprite.TRANS_ROT180); + else + setTransform(Sprite.TRANS_NONE); + } + + public int getRefPixelY() + { + return (int) y; + } + + public int getRefPixelX() + { + return (int) x; + } + + private void move() + { + if (getFrame() < CAR_FRAMES) + { + if (dir) + y += speed * cf; + else + y += speed / cf; + if (isPolice() && y < spTank.getRefPixelY() && y > 0) + { + if (spTank.getRefPixelX() < x) + x -= Math.ceil(controlSpeed / 3.0); + else if (spTank.getRefPixelX() > x) + x += Math.ceil(controlSpeed / 3.0); + if (x <= w / 5) + x = w / 5; + if (x >= w - w / 5) + x = w - w / 5; + } + else if (fps >= 15) + for (int i = 0; i < maxCars; i++) + { + if (cars[i] != this) + { + boolean inWidth = Math.abs(x - cars[i].getRefPixelX()) <= imCar.getWidth() / CAR_FRAMES; + boolean inHeight = Math.abs(y - cars[i].getRefPixelY()) <= imCar.getHeight(); + if (inWidth && inHeight) + if (x < cars[i].getRefPixelX() && x > cf) + x -= cf; + else + x += cf; + } + boolean inWidth = Math.abs(x - men[i].getRefPixelX()) <= imMan.getWidth(); + boolean inHeight = Math.abs(y - men[i].getRefPixelY()) <= imMan.getHeight() * 2; + if (inWidth && inHeight) + if (x < men[i].getRefPixelX()) + x -= cf; + else + x += cf; + } + boolean inWidth = Math.abs(x - spTank.getRefPixelX()) <= imTank.getWidth(); + boolean inHeight = Math.abs(y - spTank.getRefPixelY()) <= imTank.getHeight() * 2; + if (inWidth && inHeight) + if (x < spTank.getRefPixelX()) + x -= cf; + else + x += cf; + if (x <= w / 5) + x = w / 5; + if (x >= w - w / 5) + x = w - w / 5; + } + else + y += speed; + if (y > h + 10) + reset(); + setRefPixelPosition(getRefPixelX(), getRefPixelY()); + + } + + private void kill() + { + if (getFrame() < CAR_FRAMES) + { + setFrame(CAR_FRAMES + getFrame()); + boom = true; + spBoom.setRefPixelPosition(getRefPixelX(), getRefPixelY()); + spBoom.setFrame(0); + } + } + } +} diff --git a/src/res/about.txt b/src/res/about.txt new file mode 100644 index 0000000..fb50703 --- /dev/null +++ b/src/res/about.txt @@ -0,0 +1,41 @@ +Цель игры - набрать как можно больше очков, уничтожая машины и сбивая мотоциклистов. +Полученные очки можно в магазине обменять на улучшения танка. +При столкновении с машиной снимается жизнь. +Полицейская машина будет стараться специально врезаться в танк. +Если кончается топливо, снимается жизнь, а топливо восстанавливается. +Если число жизней станет равно 0, то игра заканчивается. + +В Bluetooth режиме большинство параметров у обоих танков складываются. +Для соединения телефон с бОльшим экраном должен в меню "Мультиплеер" выбрать режим сервера. +Его союзник выбирает "Клиент" и после поиска нужный телефон. + + +Магазин: +- Зарядка: скорость зарядки. Не может быть меньше определенного предела. +- Ракеты: количество ракет, которые могут быть одновременно быть на экране. +- Скорость ракет: скорость, с которой летят ракеты. Не может быть больше длины ракеты, равной 12. +- Управление: скорость перемещения танка по дороге. Не может быть больше 36. Не cоветую ставить больше 5, иначе очень трудно прицелиться. +- Топливо: увеличивает размер топливного бака, соответственно танк проедет больше. +- Бомба: при активации уничтожает весь транспорт на короткое время. +- Щит: при активации танк становится неуязвим для машин. +- Сброс скорости: при активации скорость движения на дороге снижается до начальной. +- Шар Свиборга: при активации, Свиборг своим брутальным и бессердечным взглядом превращает весь транспорт в дерьмо. + Можно активировать только одного Свиборга на 30 секунд, ибо Свиборг существует только один. +- Быстрые ракеты: летят в 2 раза быстрее обычных, но не наносят вреда полиции. +- Разрывные ракеты: при попадании в цель разлетаются на части, которые тоже могут разрушать машины. +- Ракет одновременно: сколько танк может выпустить обычных ракет за залп.. +- Мега-ракеты: действуют как разрывныя, но выпущенные после разрыва ракеты так же способны разлетаться, и.т.д. + +Управление: +Вверх, Вниз, Влево, Вправо - управление движением +2, 4, 6, 8 - управление движением +5 - выстрел +Держать * - выход +# - активировать бомбу +0 - включить/выключить щит +9 - сброс скорости +7 - включить Свиборга +1 - переключить режим стрельбы + +Автор - P@bloid +Сделано для конкурса на http://annimon.com/ diff --git a/src/res/bomb.png b/src/res/bomb.png new file mode 100644 index 0000000000000000000000000000000000000000..40f4ab0f6e12304a20ff7b1a6f48612f145484c3 GIT binary patch literal 206 zcmeAS@N?(olHy`uVBq!ia0vp^96-#+#0(_!Ew-`(DVB6cUq=Rpjs4tz5xI4%Af+Wie!&b5&u*jvITt-$978nD$4-1J*{s0RlE{3B zZH~0ST!)wiQ~!o%+AX;8$^En4$)|iyAB2T__fPoepyKs!CPRQwpxO;BksR)VsngV7 z-1@}QzQu;IFV0(uS!H+9vvUh{8Z=hd-TM*Cs28+|L!qNfhGR{N+`;PX<&LKXjd#TQ z@`>}Sb=7>mcit+zyN7Yj5x!$BH%kTnS?@EgbKCMwH?Mh1-o9yfuC1tEE#`VK?}^!K zPqzctihuWXWKC|Jc`x+(W54x}*4%7Wu$6OO|7L50&4Rob{-_f+Yb;Ej*q@RzN%{9j RHw@@G22WQ%mvv4FO#o8ufS~{Y literal 0 HcmV?d00001 diff --git a/src/res/car.png b/src/res/car.png new file mode 100644 index 0000000000000000000000000000000000000000..ac390ceee22a438f188a4dd8c287463607b59779 GIT binary patch literal 1076 zcmV-41k3x0P)$~?WIQq}Ff&+1GbB1RKK}p!H8(U!GB#8)AvrdIKtexHKQTf< zM@m6AS3fI2L0mgQZbwK)TS-W7Jjc#6D-lB<%Gk)NQQnW)IBtf{oNv%tc>#L(W((9PZD?&<63`~CUV z=@_X10004WQchCo}E)-$6oH5<^$Htn#)O~o7`SLF7N+_ZT`lq_*=SAX10BUZGV+WkpKK&+M9$=w&D6GSqI^5=(eXd z70*;mnoO0s189ON+0iyD-f?Up84mR3cT!E#SVqlbPN zdfE35>L~LB;;O8QtMZQ@ZUX#Z(jgustIT_WX>ju>~EJ@m;I+bOX@Oz@2GeeO5s7b>L@wu!X zTj01S%FW}@bY=a)0`1xFL41gW&vO z7e#^0DhcunW^j0RBMrz&^K@|xk+@uX{-V?Y0S>kc9LBRM|1Y0wf9uYf(7EeFp4eRe z9ku(Uq5EmqgT+3^``Jns1y1C9BHF+(p_40N8q=r9RUNfyA9`my{BM}HX{$@K>cL~D sWKJIx6OKK@d`)wgRf4r&qWymRTt1dn)0En5fi^ODy85}Sb4q9e02Ss_V*mgE literal 0 HcmV?d00001 diff --git a/src/res/fuel.png b/src/res/fuel.png new file mode 100644 index 0000000000000000000000000000000000000000..db7beec35a6db3c077c17c93abda59bbe25d4697 GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)P#0(^x&F&chDaPU;cPEB*=VV?2IXnSAA+A80 zp@Bhgtzhxo;;C|6T^=NV+7*FPOpM*^M+HN3z5EZz wkxv|`NXXO0F@)oKvPZ%Xh89*HHXbGh(LYQdtN*q?2g)*dy85}Sb4q9e0MMi=?f?J) literal 0 HcmV?d00001 diff --git a/src/res/man.png b/src/res/man.png new file mode 100644 index 0000000000000000000000000000000000000000..868d8addce9125f461c0001a3623ac83433aa1a8 GIT binary patch literal 228 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CF!VDyfm=>J`QjEnx?oJHr&dIz4a`*#$LR>w8 z42D%IDh&S_LjUJ7%w)KIAEd4%$S;_|;n|He5GTpo-G!lpRn`N@;VkfoEM{Qf76xHP zhFNnYfP(BLp1!W^w^-SD1sP8M{>lava`bd@4B@yg+I5<@!GPze&um5y^#_|7lq3~| z^8e4w@ZY9$dEH`eKlx>g?nE8B67F zZX?=QyPe~Q+|_n{-*ciaE$2`)&74#NPz z``Untq;M)oIt^-mmyI2yDf&WM%!S!P4H{n5&fg^oh z8Nh1kr+HOIL6qHxIykf=vXWbMzjyu6cbOMAJy<~tACijK-E}oNR-+4Uv9r%_k4Hb8 zj1!{~0NNIleR6HOnwexHswM!R7~>$xZ+SrDwmO-Fw+3OnPxAN}mu2Q%E*Sul!7x4? zj>jlKgwk)NGxdhl{hjD**3KP)Px#Gf+%aMNm5J3QGe3PXz#21rJ^Z1ZV^xUg{h#)L z*0x_~=ceKhW+=Dq7N)izLgnxJ^WF!n5=v`t&{~LQ2naZAAyA>j69Y3I|4~SIkDd`@Sk^C`AoA;H=T-YsG$cM<~ zL1OzA_jI~Es(X;|pjeQYd~??N09KJI@&!8I-|i#k_#da}>uf;f#P;LRAm@xfr2PrW T_kJ%D00000NkvXXu0mjf*T$Am literal 0 HcmV?d00001 diff --git a/src/res/tick.png b/src/res/tick.png new file mode 100644 index 0000000000000000000000000000000000000000..0aaa3acb410f79d617eef4243da7df03eda78dda GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPF