Initial
This commit is contained in:
commit
67a3be6fcb
83
build.xml
Normal file
83
build.xml
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- You may freely edit this file. See commented blocks below for -->
|
||||||
|
<!-- some examples of how to customize the build. -->
|
||||||
|
<!-- (If you delete it and reopen the project it will be recreated.) -->
|
||||||
|
<project name="S3DGame" default="jar" basedir=".">
|
||||||
|
<description>Builds, tests, and runs the project .</description>
|
||||||
|
<import file="nbproject/build-impl.xml"/>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
There exist several targets which are by default empty and which can be
|
||||||
|
used for execution of your tasks. These targets are usually executed
|
||||||
|
before and after some main targets. They are:
|
||||||
|
|
||||||
|
pre-init: called before initialization of project properties
|
||||||
|
post-init: called after initialization of project properties
|
||||||
|
pre-preprocess: called before text preprocessing of sources
|
||||||
|
post-preprocess: called after text preprocessing of sources
|
||||||
|
pre-compile: called before source compilation
|
||||||
|
post-compile: called after source compilation
|
||||||
|
pre-obfuscate: called before obfuscation
|
||||||
|
post-obfuscate: called after obfuscation
|
||||||
|
pre-preverify: called before preverification
|
||||||
|
post-preverify: called after preverification
|
||||||
|
pre-jar: called before jar building
|
||||||
|
post-jar: called after jar building
|
||||||
|
pre-build: called before final distribution building
|
||||||
|
post-build: called after final distribution building
|
||||||
|
pre-clean: called before cleaning build products
|
||||||
|
post-clean: called after cleaning build products
|
||||||
|
|
||||||
|
Example of pluging a my-special-task after the compilation could look like
|
||||||
|
|
||||||
|
<target name="post-compile">
|
||||||
|
<my-special-task>
|
||||||
|
<fileset dir="${build.classes.dir}"/>
|
||||||
|
</my-special-task>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
For list of available properties check the imported
|
||||||
|
nbproject/build-impl.xml file.
|
||||||
|
|
||||||
|
Other way how to customize the build is by overriding existing main targets.
|
||||||
|
The target of interest are:
|
||||||
|
|
||||||
|
preprocess: preprocessing
|
||||||
|
extract-libs: extraction of libraries and resources
|
||||||
|
compile: compilation
|
||||||
|
create-jad: construction of jad and jar manifest source
|
||||||
|
obfuscate: obfuscation
|
||||||
|
preverify: preverification
|
||||||
|
jar: jar archive building
|
||||||
|
run: execution
|
||||||
|
debug: execution in debug mode
|
||||||
|
build: building of the final distribution
|
||||||
|
javadoc: javadoc generation
|
||||||
|
|
||||||
|
Example of overriding the target for project execution could look like
|
||||||
|
|
||||||
|
<target name="run" depends="init,jar">
|
||||||
|
<my-special-exec jadfile="${dist.dir}/${dist.jad}"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
Be careful about correct dependencies when overriding original target.
|
||||||
|
Again, for list of available properties which you can use check the target
|
||||||
|
you are overriding in nbproject/build-impl.xml file.
|
||||||
|
|
||||||
|
A special target for-all-configs can be used to run some specific targets for
|
||||||
|
all project configurations in a sequence. File nbproject/build-impl.xml
|
||||||
|
already contains some "for-all" targets:
|
||||||
|
|
||||||
|
jar-all
|
||||||
|
javadoc-all
|
||||||
|
clean-all
|
||||||
|
|
||||||
|
Example of definition of target iterating over all project configurations:
|
||||||
|
|
||||||
|
<target name="jar-all">
|
||||||
|
<property name="target.to.call" value="jar"/>
|
||||||
|
<antcall target="for-all-configs"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
-->
|
||||||
|
</project>
|
1247
nbproject/build-impl.xml
Normal file
1247
nbproject/build-impl.xml
Normal file
File diff suppressed because it is too large
Load Diff
8
nbproject/genfiles.properties
Normal file
8
nbproject/genfiles.properties
Normal file
@ -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=0e3f44a9
|
||||||
|
build.xml.script.CRC32=94773986
|
||||||
|
build.xml.stylesheet.CRC32=9c6a911d
|
||||||
|
nbproject/build-impl.xml.data.CRC32=0e3f44a9
|
||||||
|
nbproject/build-impl.xml.script.CRC32=1a4b0164
|
||||||
|
nbproject/build-impl.xml.stylesheet.CRC32=e46c2d22
|
7
nbproject/private/private.properties
Normal file
7
nbproject/private/private.properties
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#Sun, 25 Mar 2012 12:33:16 +0200
|
||||||
|
app-version.autoincrement=true
|
||||||
|
config.active=
|
||||||
|
deployment.counter=51
|
||||||
|
deployment.number=0.0.50
|
||||||
|
javadoc.preview=true
|
||||||
|
netbeans.user=C\:\\Users\\aNNiMON\\.netbeans\\7.1
|
4
nbproject/private/private.xml
Normal file
4
nbproject/private/private.xml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
|
||||||
|
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"/>
|
||||||
|
</project-private>
|
105
nbproject/project.properties
Normal file
105
nbproject/project.properties
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
abilities=MMAPI=1.1,SATSAJCRMI=1.0,SATSACRYPTO=1.0,JSR82=1.1,NOKIAUI=1.0,JSR226=1.0,capuchin=1.0,MIDP=2.1,JSR229=1.1.0,SATSAAPDU=1.0,CLDC=1.1,JSR177=1.0,JSR179=1.0.1,eSWT=1.1,J2MEWS=1.0,VSCL=2.1,WMA=2.0,JSR172=1.0,JSR256=1.1,SEMC_EXT_JP8=1.0,ColorScreen,NokiaUI=1.0,OBEX=1.0,JSR238=1.0,JSR239=1.0,JSR211=1.0,JSR234=1.0,ScreenWidth=240,MascotV3=1.0,JSR75=1.0,IAPInfo=1.0,SATSAPKI=1.0,JSR184=1.1,ScreenHeight=321,ScreenColorDepth=8,JSR180=1.0.1,J2MEXMLRPC=1.0,
|
||||||
|
all.configurations=\
|
||||||
|
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
|
||||||
|
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=Flood-It.jad
|
||||||
|
dist.jar=Flood-It.jar
|
||||||
|
dist.javadoc.dir=${dist.dir}/doc
|
||||||
|
dist.root.dir=dist
|
||||||
|
extra.classpath=
|
||||||
|
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=false
|
||||||
|
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=
|
||||||
|
main.class=
|
||||||
|
main.class.class=applet
|
||||||
|
manifest.apipermissions=
|
||||||
|
manifest.file=manifest.mf
|
||||||
|
manifest.is.liblet=false
|
||||||
|
manifest.jad=
|
||||||
|
manifest.manifest=
|
||||||
|
manifest.midlets=MIDlet-1: Flood-It,/icon.png,Main\n
|
||||||
|
manifest.others=MIDlet-Vendor: aNNiMON\nMIDlet-Name: Flood-It\nMIDlet-Version: 1.0.1\n
|
||||||
|
manifest.pushregistry=
|
||||||
|
name=S3DGame
|
||||||
|
no.dependencies=false
|
||||||
|
nokiaS80.application.icon=
|
||||||
|
obfuscated.classes.dir=${build.dir}/obfuscated
|
||||||
|
obfuscation.custom=@E:\\SETUPS\\Disk\\Programming\\Java\\annimon.pro
|
||||||
|
obfuscation.level=1
|
||||||
|
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,JSR211-1.0,JSR82-1.1,JSR177-1.0,JSR234-1.0,SATSA-APDU-1.0,capuchin-1.0,J2ME-WS-1.0,J2ME-XMLRPC-1.0,SATSA-JCRMI-1.0,SATSA-CRYPTO-1.0,JSR239-1.0,MascotV3-1.0,JSR238-1.0,MMAPI-1.1,JSR256-1.1,NokiaUI-1.0,IAPInfo-1.0,JSR229-1.1.0,SATSA-PKI-1.0,JSR180-1.0.1,JSR226-1.0,SEMC_EXT_JP8-1.0,VSCL-2.0,VSCL-2.1,eSWT-1.1,JSR75-1.0,JSR184-1.1,JSR179-1.0.1
|
||||||
|
platform.bootclasspath=${platform.home}/lib/eswt.jar:${platform.home}/lib/mascotv3.jar:${platform.home}/lib/jsr226.jar:${platform.home}/lib/jsr256.jar:${platform.home}/lib/satsa-crypto.jar:${platform.home}/lib/jsr229.jar:${platform.home}/lib/jsr238.jar:${platform.home}/lib/j2me-xmlrpc.jar:${platform.home}/lib/jsr211.jar:${platform.home}/lib/vscl21.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/nokiaext.jar:${platform.home}/lib/capuchin.jar:${platform.home}/lib/jsr239.jar:${platform.home}/lib/jsr75.jar:${platform.home}/lib/satsa-pki.jar:${platform.home}/lib/jsr179.jar:${platform.home}/lib/jsr180.jar:${platform.home}/lib/iapinfo.jar:${platform.home}/lib/vscl.jar:${platform.home}/lib/mmapi.jar:${platform.home}/lib/j2me-ws.jar:${platform.home}/lib/wma20.jar:${platform.home}/lib/jsr234.jar:${platform.home}/lib/semc_ext_jp8.jar:${platform.home}/lib/cldcapi11.jar:${platform.home}/lib/midpapi20.jar
|
||||||
|
platform.configuration=CLDC-1.1
|
||||||
|
platform.device=SonyEricsson_JP8_240x320_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
|
||||||
|
resources.dir=resources
|
||||||
|
run.cmd.options=
|
||||||
|
run.jvmargs=
|
||||||
|
run.method=STANDARD
|
||||||
|
run.security.domain=trusted
|
||||||
|
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=E1760129
|
||||||
|
semc.certificate.path=
|
||||||
|
semc.private.key.password=
|
||||||
|
semc.private.key.path=
|
||||||
|
sign.alias=
|
||||||
|
sign.enabled=false
|
||||||
|
sign.keystore=
|
||||||
|
src.dir=src
|
||||||
|
use.emptyapis=true
|
||||||
|
use.preprocessor=true
|
10
nbproject/project.xml
Normal file
10
nbproject/project.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||||
|
<type>org.netbeans.modules.kjava.j2meproject</type>
|
||||||
|
<configuration>
|
||||||
|
<data xmlns="http://www.netbeans.org/ns/j2me-project">
|
||||||
|
<name>S3DGame</name>
|
||||||
|
<minimum-ant-version>1.6</minimum-ant-version>
|
||||||
|
</data>
|
||||||
|
</configuration>
|
||||||
|
</project>
|
207
src/About.java
Normal file
207
src/About.java
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
/*
|
||||||
|
* aNNiMON 2010
|
||||||
|
* For more info visit http://annimon.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* На основе класса MultiLineText от А.С. Ледкова
|
||||||
|
* www.mobilab.ru
|
||||||
|
*/
|
||||||
|
import java.util.Vector;
|
||||||
|
import javax.microedition.lcdui.Canvas;
|
||||||
|
import javax.microedition.lcdui.Font;
|
||||||
|
import javax.microedition.lcdui.Graphics;
|
||||||
|
import javax.microedition.lcdui.Image;
|
||||||
|
|
||||||
|
public class About extends Canvas {
|
||||||
|
|
||||||
|
/* Фон */
|
||||||
|
private Image background;
|
||||||
|
|
||||||
|
/* Шрифт */
|
||||||
|
private Font def;
|
||||||
|
|
||||||
|
/* Размер шрифта */
|
||||||
|
private int defHeight;
|
||||||
|
|
||||||
|
/* Максимальная высота выводимого текста */
|
||||||
|
private int maxHeight;
|
||||||
|
|
||||||
|
/* Высота, с которой будет отрисовываться текст */
|
||||||
|
private int minHeight;
|
||||||
|
|
||||||
|
/* Шаг при прокрутке текста */
|
||||||
|
private int stepY;
|
||||||
|
|
||||||
|
/* Массив строк */
|
||||||
|
private Vector strLines;
|
||||||
|
|
||||||
|
/* Текущая высота текста */
|
||||||
|
private int textHeight;
|
||||||
|
|
||||||
|
/* Размер экрана */
|
||||||
|
private int w, h;
|
||||||
|
|
||||||
|
public About(String path) {
|
||||||
|
setFullScreenMode(true);
|
||||||
|
w = getWidth();
|
||||||
|
h = getHeight();
|
||||||
|
def = Font.getDefaultFont();
|
||||||
|
stepY = defHeight = def.getHeight() + 2;
|
||||||
|
maxHeight = h - defHeight - 1;
|
||||||
|
initParameters(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBackground(Image image) {
|
||||||
|
background = Util.smooth(image, 5, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void paint(Graphics g) {
|
||||||
|
g.drawImage(background, 0, 0, Graphics.LEFT | Graphics.TOP);
|
||||||
|
g.setFont(def);
|
||||||
|
g.setColor(0xFFFFFF);
|
||||||
|
g.drawString("Flood-It", w / 2, 1, 17);
|
||||||
|
g.setClip(0, defHeight + 1, w, maxHeight);
|
||||||
|
|
||||||
|
int y1 = minHeight;
|
||||||
|
|
||||||
|
for (int i = 0; i < strLines.size(); i++) {
|
||||||
|
if ((y1 + defHeight) > 0) {
|
||||||
|
g.drawString(strLines.elementAt(i).toString(), 1, defHeight + 5 + y1, Graphics.LEFT | Graphics.TOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
y1 = y1 + defHeight;
|
||||||
|
|
||||||
|
if (y1 > maxHeight) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g.setClip(0, 0, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void keyPressed(int key) {
|
||||||
|
int ga = getGameAction(key);
|
||||||
|
|
||||||
|
if (ga == UP) moveUp();
|
||||||
|
else if (ga == DOWN) moveDown();
|
||||||
|
else if (ga == LEFT) pageUp();
|
||||||
|
else if (ga == RIGHT) pageDown();
|
||||||
|
else if ((ga == FIRE) || (key == -6) || (key == -7) || (key == KEY_STAR)) {
|
||||||
|
Menu.showMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Расчет параметров
|
||||||
|
*/
|
||||||
|
private void initParameters(String path) {
|
||||||
|
|
||||||
|
// Разбиваем строку на массив строк
|
||||||
|
strLines = new Vector();
|
||||||
|
|
||||||
|
String str = Util.getText(path, true);
|
||||||
|
String[] arr = Util.splitString(str, "\n");
|
||||||
|
|
||||||
|
for (int i = 0; i < arr.length; i++) {
|
||||||
|
String substr = arr[i];
|
||||||
|
int i0 = 0,
|
||||||
|
in = 0,
|
||||||
|
jw = 0; // Смещение от начала строки
|
||||||
|
int imax = substr.length(); // Длина строки
|
||||||
|
boolean isexit = true;
|
||||||
|
|
||||||
|
minHeight = 0;
|
||||||
|
|
||||||
|
while (isexit) {
|
||||||
|
int space = substr.indexOf(" ", i0 + 1);
|
||||||
|
|
||||||
|
if (space <= i0) {
|
||||||
|
space = imax;
|
||||||
|
isexit = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int j = def.stringWidth(substr.substring(i0, space));
|
||||||
|
|
||||||
|
if (jw + j < w) { // Слово вмещается
|
||||||
|
jw = jw + j;
|
||||||
|
i0 = space;
|
||||||
|
} else { // Слово не вмещается
|
||||||
|
strLines.addElement(substr.substring(in, i0));
|
||||||
|
in = i0 + 1;
|
||||||
|
jw = j;
|
||||||
|
|
||||||
|
if (j > w) { // Слово полностью не вмещается в строке
|
||||||
|
space = i0;
|
||||||
|
|
||||||
|
while (jw > w) {
|
||||||
|
j = 0;
|
||||||
|
|
||||||
|
while (j < w) {
|
||||||
|
space++;
|
||||||
|
j = def.stringWidth(substr.substring(in, space));
|
||||||
|
}
|
||||||
|
|
||||||
|
space = space - 1;
|
||||||
|
j = def.stringWidth(substr.substring(in, space));
|
||||||
|
strLines.addElement(substr.substring(in, space));
|
||||||
|
jw = jw - j;
|
||||||
|
i0 = space;
|
||||||
|
in = space;
|
||||||
|
}
|
||||||
|
|
||||||
|
jw = 0;
|
||||||
|
} else {
|
||||||
|
i0 = space;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strLines.addElement(substr.substring(in, imax));
|
||||||
|
}
|
||||||
|
|
||||||
|
textHeight = strLines.size() * defHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void moveDown() {
|
||||||
|
if (textHeight > maxHeight) {
|
||||||
|
minHeight = minHeight - stepY;
|
||||||
|
|
||||||
|
if (maxHeight - minHeight > textHeight) {
|
||||||
|
minHeight = maxHeight - textHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void moveUp() {
|
||||||
|
if (textHeight > maxHeight) {
|
||||||
|
minHeight = minHeight + stepY;
|
||||||
|
|
||||||
|
if (minHeight > 0) {
|
||||||
|
minHeight = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pageUp() {
|
||||||
|
if (textHeight > maxHeight) {
|
||||||
|
minHeight = minHeight + maxHeight;
|
||||||
|
|
||||||
|
if (minHeight > 0) {
|
||||||
|
minHeight = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pageDown() {
|
||||||
|
if (textHeight > maxHeight) {
|
||||||
|
minHeight = minHeight - maxHeight;
|
||||||
|
|
||||||
|
if (maxHeight - minHeight > textHeight) {
|
||||||
|
minHeight = maxHeight - textHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
87
src/Box.java
Normal file
87
src/Box.java
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
|
||||||
|
import com.s3d.Mesh;
|
||||||
|
import com.s3d.Square;
|
||||||
|
import com.s3d.Vertex;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* aNNiMON 2012
|
||||||
|
* For more info visit http://annimon.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Создаёт кубик из поверхностей.
|
||||||
|
* @author aNNiMON
|
||||||
|
*/
|
||||||
|
public class Box {
|
||||||
|
private Vertex[][] box;
|
||||||
|
private int size;
|
||||||
|
|
||||||
|
public Box(int size) {
|
||||||
|
this.size = size;
|
||||||
|
box = new Vertex[6][];
|
||||||
|
setVertexes();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mesh getBox(int color) {
|
||||||
|
Mesh mesh = new Mesh();
|
||||||
|
|
||||||
|
for (int i = 0; i < box.length; i++) {
|
||||||
|
mesh.addFace(new Square(box[i][0], box[i][1], box[i][2], box[i][3], color));
|
||||||
|
}
|
||||||
|
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setVertexes() {
|
||||||
|
int i = size / 2;
|
||||||
|
|
||||||
|
// Низ
|
||||||
|
box[0] = new Vertex[] {
|
||||||
|
new Vertex(-i, -i, -i),
|
||||||
|
new Vertex(-i, -i, i),
|
||||||
|
new Vertex(i, -i, i),
|
||||||
|
new Vertex(i, -i, -i)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Верх
|
||||||
|
box[1] = new Vertex[] {
|
||||||
|
new Vertex(-i, i, -i),
|
||||||
|
new Vertex(-i, i, i),
|
||||||
|
new Vertex(i, i, i),
|
||||||
|
new Vertex(i, i, -i)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Фронт
|
||||||
|
box[2] = new Vertex[] {
|
||||||
|
new Vertex(i, -i, i),
|
||||||
|
new Vertex(-i, -i, i),
|
||||||
|
new Vertex(-i, i, i),
|
||||||
|
new Vertex(i, i, i)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Бэк
|
||||||
|
box[3] = new Vertex[] {
|
||||||
|
new Vertex(-i, -i, -i),
|
||||||
|
new Vertex(i, -i, -i),
|
||||||
|
new Vertex(i, i, -i),
|
||||||
|
new Vertex(-i, i, -i)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Лево
|
||||||
|
box[4] = new Vertex[] {
|
||||||
|
new Vertex(-i, -i, -i),
|
||||||
|
new Vertex(-i, -i, i),
|
||||||
|
new Vertex(-i, i, i),
|
||||||
|
new Vertex(-i, i, -i)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Право
|
||||||
|
box[5] = new Vertex[] {
|
||||||
|
new Vertex(i, -i, -i),
|
||||||
|
new Vertex(i, -i, i),
|
||||||
|
new Vertex(i, i, i),
|
||||||
|
new Vertex(i, i, -i)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
284
src/Canv.java
Normal file
284
src/Canv.java
Normal file
@ -0,0 +1,284 @@
|
|||||||
|
/*
|
||||||
|
* aNNiMON 2012
|
||||||
|
* For more info visit http://annimon.com/
|
||||||
|
*/
|
||||||
|
import com.s3d.Matrix3D;
|
||||||
|
import com.s3d.Camera;
|
||||||
|
import javax.microedition.lcdui.Canvas;
|
||||||
|
import javax.microedition.lcdui.Graphics;
|
||||||
|
import javax.microedition.lcdui.Image;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author aNNiMON
|
||||||
|
*/
|
||||||
|
public class Canv extends Canvas implements Runnable {
|
||||||
|
|
||||||
|
/* Размер шага при перемещении в пространстве */
|
||||||
|
private static final int STEP_SIZE = 5;
|
||||||
|
|
||||||
|
/* Режимы управления */
|
||||||
|
private static final byte
|
||||||
|
MODE_GAME = 0,
|
||||||
|
MODE_SET_POSITION = 1,
|
||||||
|
MODE_SET_ROTATION = 2;
|
||||||
|
|
||||||
|
/* Двойная буферизация */
|
||||||
|
private Graphics G;
|
||||||
|
private Image I;
|
||||||
|
|
||||||
|
/* Цвет заливки */
|
||||||
|
private byte fillId;
|
||||||
|
|
||||||
|
/* Игра */
|
||||||
|
public FloodIt game;
|
||||||
|
|
||||||
|
/* Матрица, необходимая для отрисовки модели */
|
||||||
|
private Matrix3D matrix;
|
||||||
|
|
||||||
|
/* Режим управления */
|
||||||
|
private int mode;
|
||||||
|
|
||||||
|
/* Положение в пространстве */
|
||||||
|
private int modelX, modelY, modelZ;
|
||||||
|
|
||||||
|
/* Углы поворота модели */
|
||||||
|
private int rotX, rotY, rotZ;
|
||||||
|
|
||||||
|
/* Софтбар заливаемых цветов */
|
||||||
|
private SoftBar soft;
|
||||||
|
|
||||||
|
/* Надпись в заголовке */
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
/* Размер экрана */
|
||||||
|
private int w, h;
|
||||||
|
|
||||||
|
public Canv() {
|
||||||
|
setFullScreenMode(true);
|
||||||
|
w = getWidth();
|
||||||
|
h = getHeight();
|
||||||
|
I = Image.createImage(w, h);
|
||||||
|
G = I.getGraphics();
|
||||||
|
initCameraMatrix();
|
||||||
|
soft = new SoftBar();
|
||||||
|
|
||||||
|
// Режим управления
|
||||||
|
mode = MODE_GAME;
|
||||||
|
title = "Flood-It";
|
||||||
|
fillId = 0;
|
||||||
|
new Thread(this).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initCameraMatrix() {
|
||||||
|
// Установить параметры камеры
|
||||||
|
Camera.w = w;
|
||||||
|
Camera.h = h;
|
||||||
|
|
||||||
|
// Дальность рендеринга = 5000
|
||||||
|
Camera.limit = 5000;
|
||||||
|
game = new FloodIt(Rms.lastTableSize);
|
||||||
|
matrix = new Matrix3D();
|
||||||
|
|
||||||
|
// Углы поворота
|
||||||
|
rotX = 15;
|
||||||
|
rotY = -15;
|
||||||
|
rotZ = 0;
|
||||||
|
|
||||||
|
// Координаты
|
||||||
|
modelX = 5;
|
||||||
|
modelY = 40;
|
||||||
|
modelZ = 590 + (Rms.lastTableSize - 14) * 36;
|
||||||
|
conversions();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paintTableOptions(Graphics g, int tableSize) {
|
||||||
|
if (game.getTableSize() != tableSize) game.setTableSize(tableSize);
|
||||||
|
modelZ = 590 + (tableSize - 14) * 36;
|
||||||
|
conversions();
|
||||||
|
g.setGrayScale(250);
|
||||||
|
g.drawString(String.valueOf(tableSize), w / 2, 5, Graphics.TOP | Graphics.HCENTER);
|
||||||
|
game.paint(g, matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paint(Graphics g) {
|
||||||
|
G.setColor(0x00);
|
||||||
|
G.fillRect(0, 0, w, h);
|
||||||
|
game.paint(G, matrix);
|
||||||
|
soft.paint(G, fillId);
|
||||||
|
G.setColor(0xFFFFFF);
|
||||||
|
G.drawString(title, w / 2, 0, Graphics.TOP | Graphics.HCENTER);
|
||||||
|
|
||||||
|
//
|
||||||
|
g.drawImage(I, 0, 0, Graphics.TOP | Graphics.LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Преобразования
|
||||||
|
*/
|
||||||
|
private void conversions() {
|
||||||
|
// Сбросываем настройки матрицы
|
||||||
|
matrix.unit();
|
||||||
|
|
||||||
|
// Поворачиваем по всем осям
|
||||||
|
matrix.xrot(rotY);
|
||||||
|
matrix.yrot(rotX);
|
||||||
|
matrix.zrot(rotZ);
|
||||||
|
|
||||||
|
// Устанавливаем координаты модели
|
||||||
|
matrix.translate(modelX, modelY, modelZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void sizeChanged(int w, int h) {
|
||||||
|
this.w = getWidth();
|
||||||
|
this.h = getHeight();
|
||||||
|
I = Image.createImage(w, h);
|
||||||
|
G = I.getGraphics();
|
||||||
|
super.sizeChanged(w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void keyPressed(int key) {
|
||||||
|
int ga = getGameAction(key);
|
||||||
|
|
||||||
|
if (key == KEY_NUM0) {
|
||||||
|
nextMode();
|
||||||
|
return;
|
||||||
|
} else if ((key == -7) || (key == -6) || (key == KEY_STAR)) {
|
||||||
|
Menu.showMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == MODE_GAME) {
|
||||||
|
if ( (key >= KEY_NUM1) && (key <= KEY_NUM6) ) {
|
||||||
|
fillId = (byte) (key - KEY_NUM1);
|
||||||
|
game.fill(fillId);
|
||||||
|
} else keyModeGame(ga, key);
|
||||||
|
} else if (mode == MODE_SET_POSITION) {
|
||||||
|
keyModeSetPosition(ga, key);
|
||||||
|
} else if (mode == MODE_SET_ROTATION) {
|
||||||
|
keyModeSetRotation(ga, key);
|
||||||
|
}
|
||||||
|
conversions();
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void nextMode() {
|
||||||
|
mode++;
|
||||||
|
if (mode > MODE_SET_ROTATION) {
|
||||||
|
mode = MODE_GAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == MODE_GAME) {
|
||||||
|
title = "Flood-It";
|
||||||
|
} else if (mode == MODE_SET_POSITION) {
|
||||||
|
title = Language.getMessage(Language.POSITION);
|
||||||
|
} else if (mode == MODE_SET_ROTATION) {
|
||||||
|
title = Language.getMessage(Language.ROTATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void keyModeSetRotation(int ga, int key) {
|
||||||
|
// Увеличиваем угол поворота
|
||||||
|
switch (ga) {
|
||||||
|
case LEFT:
|
||||||
|
rotX -= STEP_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIGHT:
|
||||||
|
rotX += STEP_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UP:
|
||||||
|
rotY += STEP_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DOWN:
|
||||||
|
rotY -= STEP_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
if (key == KEY_NUM1) rotZ += STEP_SIZE;
|
||||||
|
else if (key == KEY_NUM3) rotZ -= STEP_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rotX > 360) rotX = 1;
|
||||||
|
if (rotY > 360) rotY = 1;
|
||||||
|
if (rotZ > 360) rotZ = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void keyModeSetPosition(int ga, int key) {
|
||||||
|
// Сдвигаем координаты модели
|
||||||
|
switch (ga) {
|
||||||
|
case LEFT:
|
||||||
|
modelX -= STEP_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIGHT:
|
||||||
|
modelX += STEP_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UP:
|
||||||
|
modelY += STEP_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DOWN :
|
||||||
|
modelY -= STEP_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
if (key == KEY_NUM1) modelZ += STEP_SIZE;
|
||||||
|
else if (key == KEY_NUM3) modelZ -= STEP_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void keyModeGame(int ga, int key) {
|
||||||
|
// Изменяем цвет заливки
|
||||||
|
switch (ga) {
|
||||||
|
case FIRE:
|
||||||
|
game.fill(fillId);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LEFT:
|
||||||
|
case UP:
|
||||||
|
fillId--;
|
||||||
|
if (fillId < 0) {
|
||||||
|
fillId = Main.MAX_COLORS - 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIGHT:
|
||||||
|
case DOWN:
|
||||||
|
fillId++;
|
||||||
|
if (fillId >= Main.MAX_COLORS) {
|
||||||
|
fillId = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (key == KEY_POUND) {
|
||||||
|
game.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* По окончанию игры ставим курсор в -1, а если игра не закончилась
|
||||||
|
* но курсор по прежнему -1, то ставим его в 0
|
||||||
|
*/
|
||||||
|
if (game.checkTable()) fillId = -1;
|
||||||
|
else if (fillId == -1) fillId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void keyRepeated(int key) {
|
||||||
|
keyPressed(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
while (true) {
|
||||||
|
repaint();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(5L);
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
135
src/FloodIt.java
Normal file
135
src/FloodIt.java
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
import com.s3d.Matrix3D;
|
||||||
|
import java.util.Random;
|
||||||
|
import javax.microedition.lcdui.Graphics;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* aNNiMON 2012
|
||||||
|
* For more info visit http://annimon.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author aNNiMON
|
||||||
|
*/
|
||||||
|
public class FloodIt {
|
||||||
|
|
||||||
|
private int moves; // количество ходов
|
||||||
|
private byte prevColor;
|
||||||
|
private byte[][] table; // игровое поле
|
||||||
|
private Table table3d;
|
||||||
|
private int tableSize; // размер игрового поля
|
||||||
|
|
||||||
|
public FloodIt(int tableSize) {
|
||||||
|
setTableSize(tableSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTableSize() {
|
||||||
|
return tableSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setTableSize(int tableSize) {
|
||||||
|
this.tableSize = tableSize;
|
||||||
|
Rms.lastTableSize = tableSize;
|
||||||
|
table3d = new Table(tableSize);
|
||||||
|
moves = 0;
|
||||||
|
initTable();
|
||||||
|
prevColor = table[0][0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
initTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fill(byte color) {
|
||||||
|
if (table == null) {
|
||||||
|
Main.midlet.hiscore.checkForHiscore(tableSize, moves);
|
||||||
|
initTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((color < 0) || (color >= Main.MAX_COLORS)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Закраска выбранным цветом
|
||||||
|
prevColor = table[0][0];
|
||||||
|
|
||||||
|
if (prevColor != color) {
|
||||||
|
fillTable(0, 0, color);
|
||||||
|
moves++;
|
||||||
|
}
|
||||||
|
|
||||||
|
table3d.updateTable(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paint(Graphics g, Matrix3D matrix) {
|
||||||
|
if (checkTable()) {
|
||||||
|
int w = g.getClipWidth();
|
||||||
|
int h = g.getClipHeight();
|
||||||
|
|
||||||
|
g.setColor(0xFFFFFF);
|
||||||
|
g.drawString(Language.getMessage(Language.GAME_OVER), w / 2, h / 2 - h / 16, Graphics.HCENTER | Graphics.BOTTOM);
|
||||||
|
|
||||||
|
String str = Language.getMessage(Language.MOVES) + String.valueOf(moves);// + " ходов";
|
||||||
|
|
||||||
|
g.drawString(str, w / 2, h / 2 + h / 16, Graphics.HCENTER | Graphics.TOP);
|
||||||
|
table = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
table3d.paint(g, matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initTable() {
|
||||||
|
table = new byte[tableSize][tableSize];
|
||||||
|
moves = 0;
|
||||||
|
|
||||||
|
// Генерируем игровое поле
|
||||||
|
Random rnd = new Random();
|
||||||
|
|
||||||
|
for (int i = 0; i < tableSize; i++) {
|
||||||
|
for (int j = 0; j < tableSize; j++) {
|
||||||
|
table[i][j] = (byte) rnd.nextInt(Main.MAX_COLORS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table3d.updateTable(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Заливка поля */
|
||||||
|
private void fillTable(int x, int y, byte color) {
|
||||||
|
|
||||||
|
// Проверка на выход за границы игрового поля
|
||||||
|
if ((x < 0) || (y < 0) || (x >= tableSize) || (y >= tableSize)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (table[x][y] == prevColor) {
|
||||||
|
table[x][y] = color;
|
||||||
|
|
||||||
|
// Заливаем смежные области
|
||||||
|
fillTable(x - 1, y, color);
|
||||||
|
fillTable(x + 1, y, color);
|
||||||
|
fillTable(x, y - 1, color);
|
||||||
|
fillTable(x, y + 1, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Проверка, залита ли вся область одним цветом */
|
||||||
|
public boolean checkTable() {
|
||||||
|
if (table == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte color = table[0][0];
|
||||||
|
|
||||||
|
for (int i = 0; i < tableSize; i++) {
|
||||||
|
for (int j = 0; j < tableSize; j++) {
|
||||||
|
if (table[i][j] != color) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
136
src/Hiscores.java
Normal file
136
src/Hiscores.java
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import javax.microedition.lcdui.*;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* aNNiMON 2012
|
||||||
|
* For more info visit http://annimon.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author aNNiMON
|
||||||
|
*/
|
||||||
|
public class Hiscores {
|
||||||
|
|
||||||
|
/** Сколько хранить результатов*/
|
||||||
|
private static final int MAX_STORE_SCORES = 5;
|
||||||
|
|
||||||
|
// Результаты
|
||||||
|
private int[][] scores;
|
||||||
|
private String[][] names;
|
||||||
|
|
||||||
|
public Hiscores() {
|
||||||
|
scores = new int[Main.MAX_TABLE_SIZE - Main.MIN_TABLE_SIZE + 1][MAX_STORE_SCORES];
|
||||||
|
names = new String[Main.MAX_TABLE_SIZE - Main.MIN_TABLE_SIZE + 1][MAX_STORE_SCORES];
|
||||||
|
if (Rms.firstStart) resetHiscores();
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void resetHiscores() {
|
||||||
|
for (int i = 0; i < scores.length; i++) {
|
||||||
|
for (int j = 0; j < scores[0].length; j++) {
|
||||||
|
scores[i][j] = 999;
|
||||||
|
names[i][j] = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkForHiscore(int tableSize, int newScore) {
|
||||||
|
int tableIndex = tableSize - Main.MIN_TABLE_SIZE;
|
||||||
|
|
||||||
|
if (newScore < scores[tableIndex][0]) {
|
||||||
|
askForFileName(tableIndex, newScore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paintResults(Graphics g, int scoreTableSize) {
|
||||||
|
int tableIndex = scoreTableSize - Main.MIN_TABLE_SIZE;
|
||||||
|
|
||||||
|
int width = g.getClipWidth();
|
||||||
|
int height = g.getClipHeight();
|
||||||
|
int border = width / 16;
|
||||||
|
int step = height / 3 / MAX_STORE_SCORES;
|
||||||
|
int colorStep = 100 / MAX_STORE_SCORES;
|
||||||
|
|
||||||
|
int y = height - border - (MAX_STORE_SCORES+1)*step;
|
||||||
|
|
||||||
|
g.setGrayScale(250);
|
||||||
|
g.drawString(String.valueOf(scoreTableSize), width / 2, y, Graphics.BOTTOM | Graphics.HCENTER);
|
||||||
|
|
||||||
|
for (int i = 0; i < scores[tableIndex].length; i++) {
|
||||||
|
g.setGrayScale(150 + colorStep*i);
|
||||||
|
y = height - border - (/*MAX_STORE_SCORES-1-*/i)*step;
|
||||||
|
String name = names[tableIndex][i];
|
||||||
|
if (name.length() == 0) name = Language.getMessage(Language.UNKNOWN);
|
||||||
|
g.drawString(name, border, y, Graphics.BOTTOM | Graphics.LEFT);
|
||||||
|
g.drawString(String.valueOf(scores[tableIndex][i]), width-border, y, Graphics.BOTTOM | Graphics.RIGHT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveScores(DataOutputStream dos) throws IOException {
|
||||||
|
for (int i = 0; i < scores.length; i++) {
|
||||||
|
for (int j = 0; j < scores[0].length; j++) {
|
||||||
|
dos.writeInt(scores[i][j]);
|
||||||
|
dos.writeUTF(names[i][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadScores(DataInputStream dis) throws IOException {
|
||||||
|
for (int i = 0; i < scores.length; i++) {
|
||||||
|
for (int j = 0; j < scores[0].length; j++) {
|
||||||
|
scores[i][j] = dis.readInt();
|
||||||
|
names[i][j] = dis.readUTF();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void askForFileName(final int tableIndex, final int newScore) {
|
||||||
|
final Displayable prevDisplayable = Main.midlet.dsp.getCurrent();
|
||||||
|
Form form = new Form(Language.getMessage(Language.NEW_HIGH_SCORE)+newScore);
|
||||||
|
final TextField nameTF = new TextField(Language.getMessage(Language.ENTER_YOUR_NAME), Rms.playerName, 12, TextField.ANY);
|
||||||
|
final Command ok = new Command(Language.getMessage(Language.OK), Command.OK, 1);
|
||||||
|
form.append(nameTF);
|
||||||
|
form.addCommand(ok);
|
||||||
|
form.setCommandListener(new CommandListener() {
|
||||||
|
public void commandAction(Command cmd, Displayable disp) {
|
||||||
|
if (cmd == ok) {
|
||||||
|
String text = nameTF.getString();
|
||||||
|
if (text.length() > 0) {
|
||||||
|
Rms.playerName = text;
|
||||||
|
scores[tableIndex][0] = newScore;
|
||||||
|
names[tableIndex][0] = text;
|
||||||
|
sortHiscore(tableIndex);
|
||||||
|
Main.midlet.dsp.setCurrent(prevDisplayable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Main.midlet.dsp.setCurrent(form);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sortHiscore(int index) {
|
||||||
|
int[] sortArray = scores[index];
|
||||||
|
|
||||||
|
for (int i = 0; i < sortArray.length; i++) {
|
||||||
|
int max = i;
|
||||||
|
|
||||||
|
for (int j = i + 1; j < sortArray.length; j++) {
|
||||||
|
if (sortArray[j] > sortArray[max]) max = j;
|
||||||
|
}
|
||||||
|
|
||||||
|
int temp = sortArray[max];
|
||||||
|
sortArray[max] = sortArray[i];
|
||||||
|
sortArray[i] = temp;
|
||||||
|
|
||||||
|
String tmp = names[index][max];
|
||||||
|
names[index][max] = names[index][i];
|
||||||
|
names[index][i] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
scores[index] = sortArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
72
src/Language.java
Normal file
72
src/Language.java
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* aNNiMON 2012
|
||||||
|
* For more info visit http://annimon.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author aNNiMON
|
||||||
|
*/
|
||||||
|
public class Language {
|
||||||
|
|
||||||
|
public static final byte
|
||||||
|
START = 0,
|
||||||
|
OPTIONS = 1,
|
||||||
|
HIGH_SCORE = 2,
|
||||||
|
HELP = 3,
|
||||||
|
EXIT = 4,
|
||||||
|
|
||||||
|
TABLE_SIZE = 5,
|
||||||
|
LANGUAGE = 6,
|
||||||
|
RESET_SCORES = 7,
|
||||||
|
BACK = 8,
|
||||||
|
|
||||||
|
POSITION = 9,
|
||||||
|
ROTATE = 10,
|
||||||
|
GAME_OVER = 11,
|
||||||
|
MOVES = 12,
|
||||||
|
|
||||||
|
NEW_HIGH_SCORE = 13,
|
||||||
|
ENTER_YOUR_NAME = 14,
|
||||||
|
OK = 15,
|
||||||
|
UNKNOWN = 16;
|
||||||
|
|
||||||
|
private static String[] langs = Util.getLanguages("langs.txt");
|
||||||
|
private static int currentLang = 0;
|
||||||
|
|
||||||
|
private static String[] str;
|
||||||
|
|
||||||
|
public static void nextLanguage() {
|
||||||
|
currentLang++;
|
||||||
|
if (currentLang >= langs.length) currentLang = 0;
|
||||||
|
|
||||||
|
loadLocale(langs[currentLang]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getCurrentLanguage() {
|
||||||
|
return langs[currentLang];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void detectLocale() {
|
||||||
|
String locale = System.getProperty("microedition.locale");
|
||||||
|
if ((locale != null) && (locale.length() > 1)) {
|
||||||
|
locale = locale.substring(0, 2).toLowerCase();
|
||||||
|
detectLang(locale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void detectLang(String locale) {
|
||||||
|
for (int i = 0; i < langs.length; i++) {
|
||||||
|
if (locale.equals(langs[i])) currentLang = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getMessage(int index) {
|
||||||
|
return str[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loadLocale(String locale) {
|
||||||
|
Rms.language = locale;
|
||||||
|
detectLang(locale);
|
||||||
|
str = Util.splitString(Util.getText(locale+".lang", false), "\n");
|
||||||
|
}
|
||||||
|
}
|
55
src/Main.java
Normal file
55
src/Main.java
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* aNNiMON 2012
|
||||||
|
* For more info visit http://annimon.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
import javax.microedition.lcdui.Display;
|
||||||
|
import javax.microedition.midlet.MIDlet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author aNNiMON
|
||||||
|
*/
|
||||||
|
public class Main extends MIDlet {
|
||||||
|
|
||||||
|
public static final int MIN_TABLE_SIZE = 5;
|
||||||
|
public static final int MAX_TABLE_SIZE = 25;
|
||||||
|
|
||||||
|
public static final int BOX_SIZE = 30;
|
||||||
|
public static final int[] COLORS = {
|
||||||
|
0xE81C20, 0x20B048, 0x486CF0, 0xF8F000, 0xF87C00, 0x683098
|
||||||
|
};
|
||||||
|
public static final int MAX_COLORS = 6;// количество цветов
|
||||||
|
|
||||||
|
public static Main midlet;
|
||||||
|
public About about;
|
||||||
|
public Display dsp;
|
||||||
|
public Canv floodit;
|
||||||
|
public Hiscores hiscore;
|
||||||
|
public Menu menu;
|
||||||
|
|
||||||
|
public Main() {
|
||||||
|
midlet = Main.this;
|
||||||
|
dsp = Display.getDisplay(Main.this);
|
||||||
|
hiscore = new Hiscores();
|
||||||
|
Rms.restoreOptions();
|
||||||
|
if (Rms.firstStart) {
|
||||||
|
Language.detectLocale();
|
||||||
|
Rms.language = Language.getCurrentLanguage();
|
||||||
|
}
|
||||||
|
Language.loadLocale(Rms.language);
|
||||||
|
menu = new Menu();
|
||||||
|
floodit = new Canv();
|
||||||
|
about = new About("about."+Language.getCurrentLanguage());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startApp() {
|
||||||
|
dsp.setCurrent(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pauseApp() {}
|
||||||
|
|
||||||
|
public void destroyApp(boolean ex) {
|
||||||
|
Rms.saveOptions();
|
||||||
|
notifyDestroyed();
|
||||||
|
}
|
||||||
|
}
|
326
src/Menu.java
Normal file
326
src/Menu.java
Normal file
@ -0,0 +1,326 @@
|
|||||||
|
/*
|
||||||
|
* aNNiMON 2012
|
||||||
|
* For more info visit http://annimon.com/
|
||||||
|
*/
|
||||||
|
import com.s3d.Matrix3D;
|
||||||
|
import com.s3d.Camera;
|
||||||
|
import javax.microedition.lcdui.Canvas;
|
||||||
|
import javax.microedition.lcdui.Font;
|
||||||
|
import javax.microedition.lcdui.Graphics;
|
||||||
|
import javax.microedition.lcdui.Image;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author aNNiMON
|
||||||
|
*/
|
||||||
|
public class Menu extends Canvas implements Runnable {
|
||||||
|
|
||||||
|
private static final byte
|
||||||
|
MENU_MAIN = 0,
|
||||||
|
MENU_OPTIONS = 1,
|
||||||
|
ITEM_HIGHSCORES = 2,
|
||||||
|
ITEM_SET_SIZE = 3; // настройка размера поля
|
||||||
|
|
||||||
|
private static boolean threadRun;
|
||||||
|
|
||||||
|
/* Двойная буферизация */
|
||||||
|
private Graphics G;
|
||||||
|
private Image I;
|
||||||
|
|
||||||
|
/* Меню */
|
||||||
|
private byte activeMenu;
|
||||||
|
|
||||||
|
/* Шрифт меню */
|
||||||
|
private Font font;
|
||||||
|
private int fontHeight;
|
||||||
|
|
||||||
|
/* Матрица, необходимая для отрисовки текста */
|
||||||
|
private Matrix3D matrix;
|
||||||
|
private int[] menuCursor;
|
||||||
|
private String[][] menuItems;
|
||||||
|
|
||||||
|
/* Углы поворота модели */
|
||||||
|
private float rotY, rotZ;
|
||||||
|
|
||||||
|
/* Настройки */
|
||||||
|
private int tableSize;
|
||||||
|
|
||||||
|
/* Опции */
|
||||||
|
private int scoreTableSize;
|
||||||
|
|
||||||
|
/* Трёхмерный текст на фоне */
|
||||||
|
private Text3D text;
|
||||||
|
|
||||||
|
/* Размер экрана */
|
||||||
|
private int w, h;
|
||||||
|
|
||||||
|
public Menu() {
|
||||||
|
setFullScreenMode(true);
|
||||||
|
w = getWidth();
|
||||||
|
h = getHeight();
|
||||||
|
I = Image.createImage(w, h);
|
||||||
|
G = I.getGraphics();
|
||||||
|
|
||||||
|
// Шрифт
|
||||||
|
font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_MEDIUM);
|
||||||
|
fontHeight = font.getHeight() + 2;
|
||||||
|
|
||||||
|
// Меню
|
||||||
|
activeMenu = MENU_MAIN;
|
||||||
|
menuCursor = new int[2];
|
||||||
|
menuCursor[MENU_MAIN] = 0;
|
||||||
|
menuCursor[MENU_OPTIONS] = 0;
|
||||||
|
menuItems = new String[2][];
|
||||||
|
initMenuStrings();
|
||||||
|
|
||||||
|
// Углы поворота
|
||||||
|
rotY = 0;
|
||||||
|
rotZ = 0;
|
||||||
|
|
||||||
|
// Настройки
|
||||||
|
tableSize = Rms.lastTableSize;
|
||||||
|
scoreTableSize = Rms.lastTableSize;
|
||||||
|
Camera.w = w;
|
||||||
|
Camera.h = h;
|
||||||
|
Camera.limit = 3000;
|
||||||
|
matrix = new Matrix3D();
|
||||||
|
text = new Text3D();
|
||||||
|
text.setText("Flood-It");
|
||||||
|
new Thread(this).start();
|
||||||
|
threadRun = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initMenuStrings() {
|
||||||
|
menuItems[MENU_MAIN] = new String[] {
|
||||||
|
Language.getMessage(Language.START),
|
||||||
|
Language.getMessage(Language.HIGH_SCORE),
|
||||||
|
Language.getMessage(Language.OPTIONS),
|
||||||
|
Language.getMessage(Language.HELP),
|
||||||
|
Language.getMessage(Language.EXIT)
|
||||||
|
};
|
||||||
|
menuItems[MENU_OPTIONS] = new String[] {
|
||||||
|
Language.getMessage(Language.TABLE_SIZE),
|
||||||
|
Language.getMessage(Language.LANGUAGE),
|
||||||
|
Language.getMessage(Language.RESET_SCORES),
|
||||||
|
Language.getMessage(Language.BACK)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void showMenu() {
|
||||||
|
threadRun = true;
|
||||||
|
Main.midlet.dsp.setCurrent(Main.midlet.menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paint(Graphics g) {
|
||||||
|
draw(G);
|
||||||
|
g.drawImage(I, 0, 0, Graphics.TOP | Graphics.LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Отрисовка в буфер */
|
||||||
|
private void draw(Graphics g) {
|
||||||
|
g.setColor(0x00);
|
||||||
|
g.fillRect(0, 0, w, h);
|
||||||
|
if (activeMenu != ITEM_SET_SIZE) text.paint(g, matrix);
|
||||||
|
g.setFont(font);
|
||||||
|
|
||||||
|
if (activeMenu == ITEM_HIGHSCORES) {
|
||||||
|
// Лучшие результаты
|
||||||
|
Main.midlet.hiscore.paintResults(g, scoreTableSize);
|
||||||
|
} else if (activeMenu == ITEM_SET_SIZE) {
|
||||||
|
// Установка размера поля
|
||||||
|
Main.midlet.floodit.paintTableOptions(g, tableSize);
|
||||||
|
} else {
|
||||||
|
// Отрисовываем фон курсора
|
||||||
|
int menuY = h - menuItems[activeMenu].length * fontHeight;
|
||||||
|
int menuW = w / 2;
|
||||||
|
int menuX = w / 2 - menuW / 2;
|
||||||
|
|
||||||
|
g.setGrayScale(100);
|
||||||
|
g.fillRect(menuX, menuY + menuCursor[activeMenu] * fontHeight, menuW, fontHeight);
|
||||||
|
g.setGrayScale(255);
|
||||||
|
|
||||||
|
for (int i = 0; i < menuItems[activeMenu].length; i++) {
|
||||||
|
g.drawString(menuItems[activeMenu][i], w / 2, menuY + i * fontHeight, Graphics.HCENTER | Graphics.TOP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Преобразования
|
||||||
|
*/
|
||||||
|
private void conversions() {
|
||||||
|
// Сбросываем настройки матрицы
|
||||||
|
matrix.unit();
|
||||||
|
|
||||||
|
// Поворачиваем по всем осям
|
||||||
|
matrix.yrot(rotY);
|
||||||
|
|
||||||
|
// matrix.yrot(0);
|
||||||
|
matrix.zrot(rotZ);
|
||||||
|
rotY += 0.1;
|
||||||
|
rotZ += 0.2;
|
||||||
|
|
||||||
|
if (rotY > 360) rotY = 1;
|
||||||
|
if (rotZ > 360) rotZ = 1;
|
||||||
|
|
||||||
|
// Устанавливаем координаты модели
|
||||||
|
// matrix.translate(modelX, modelY, modelZ);
|
||||||
|
matrix.translate(0, h, 1600);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void menuAction() {
|
||||||
|
if (activeMenu == MENU_MAIN) {
|
||||||
|
switch (menuCursor[activeMenu]) {
|
||||||
|
case 0: // Start Game
|
||||||
|
threadRun = false;
|
||||||
|
Main.midlet.floodit.game.setTableSize(tableSize);
|
||||||
|
Main.midlet.dsp.setCurrent(Main.midlet.floodit);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: // Hi-scores
|
||||||
|
activeMenu = ITEM_HIGHSCORES;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: // Options
|
||||||
|
activeMenu = MENU_OPTIONS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3: // Help
|
||||||
|
threadRun = false;
|
||||||
|
Main.midlet.about.setBackground(I);
|
||||||
|
Main.midlet.dsp.setCurrent(Main.midlet.about);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4: // Exit
|
||||||
|
Main.midlet.destroyApp(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (activeMenu == MENU_OPTIONS) {
|
||||||
|
switch (menuCursor[activeMenu]) {
|
||||||
|
case 0:
|
||||||
|
activeMenu = ITEM_SET_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
Language.nextLanguage();
|
||||||
|
initMenuStrings();
|
||||||
|
Main.midlet.about = new About("about."+Language.getCurrentLanguage());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
Main.midlet.hiscore.resetHiscores();
|
||||||
|
activeMenu = MENU_MAIN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:// Back
|
||||||
|
activeMenu = MENU_MAIN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void sizeChanged(int w, int h) {
|
||||||
|
this.w = getWidth();
|
||||||
|
this.h = getHeight();
|
||||||
|
I = Image.createImage(w, h);
|
||||||
|
G = I.getGraphics();
|
||||||
|
super.sizeChanged(w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void keyPressed(int key) {
|
||||||
|
int ga = getGameAction(key);
|
||||||
|
|
||||||
|
if (activeMenu == ITEM_SET_SIZE) {
|
||||||
|
keyTableOptions(ga, key);
|
||||||
|
} else if (activeMenu == ITEM_HIGHSCORES) {
|
||||||
|
keyHiscore(ga, key);
|
||||||
|
} else keyMenu(ga, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void keyRepeated(int key) {
|
||||||
|
keyPressed(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
while (true) {
|
||||||
|
if (threadRun) {
|
||||||
|
conversions();
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(5L);
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void keyMenu(int ga, int key) {
|
||||||
|
switch (ga) {
|
||||||
|
case FIRE:
|
||||||
|
menuAction();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LEFT:
|
||||||
|
case UP:
|
||||||
|
menuCursor[activeMenu]--;
|
||||||
|
if (menuCursor[activeMenu] < 0) {
|
||||||
|
menuCursor[activeMenu] = menuItems[activeMenu].length - 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIGHT:
|
||||||
|
case DOWN:
|
||||||
|
menuCursor[activeMenu]++;
|
||||||
|
if (menuCursor[activeMenu] >= menuItems[activeMenu].length) {
|
||||||
|
menuCursor[activeMenu] = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if ((key == -7) || (key == -6) || (key == KEY_STAR)) {
|
||||||
|
// Если в подменю - возврашаемся
|
||||||
|
if (activeMenu != MENU_MAIN) {
|
||||||
|
activeMenu = MENU_MAIN;
|
||||||
|
// Иначе выходим
|
||||||
|
} else {
|
||||||
|
Main.midlet.destroyApp(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void keyTableOptions(int ga, int key) {
|
||||||
|
// Настройки размера окна
|
||||||
|
if ((ga == FIRE) || (key == -7) || (key == -6) || (key == KEY_STAR)) {
|
||||||
|
activeMenu = MENU_OPTIONS;
|
||||||
|
} else tableSize = changeTableSize(ga, key, tableSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void keyHiscore(int ga, int key) {
|
||||||
|
// Настройки размера окна
|
||||||
|
if ((ga == FIRE) || (key == -7) || (key == -6) || (key == KEY_STAR)) {
|
||||||
|
activeMenu = MENU_MAIN;
|
||||||
|
} else scoreTableSize = changeTableSize(ga, key, scoreTableSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int changeTableSize(int ga, int key, int size) {
|
||||||
|
// смена размера окна
|
||||||
|
switch (ga) {
|
||||||
|
case LEFT:
|
||||||
|
case DOWN:
|
||||||
|
if (size > Main.MIN_TABLE_SIZE) {
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIGHT:
|
||||||
|
case UP:
|
||||||
|
if (size < Main.MAX_TABLE_SIZE) {
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
}
|
86
src/Rms.java
Normal file
86
src/Rms.java
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import javax.microedition.rms.InvalidRecordIDException;
|
||||||
|
import javax.microedition.rms.RecordStore;
|
||||||
|
import javax.microedition.rms.RecordStoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author aNNiMON
|
||||||
|
*/
|
||||||
|
public class Rms {
|
||||||
|
|
||||||
|
private static final String rmsName = "Flood-It";
|
||||||
|
private static RecordStore rmsStore;
|
||||||
|
|
||||||
|
public static boolean firstStart = true; // первый старт
|
||||||
|
public static String language = "";
|
||||||
|
public static int lastTableSize = 14;
|
||||||
|
public static String playerName = "Player";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Сохранение настроек
|
||||||
|
*/
|
||||||
|
public static void saveOptions() {
|
||||||
|
if (rmsStore != null) {
|
||||||
|
byte[] options = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dos = new DataOutputStream(baos);
|
||||||
|
dos.writeBoolean(false);//firstStart
|
||||||
|
dos.writeUTF(language);
|
||||||
|
dos.writeInt(lastTableSize);
|
||||||
|
dos.writeUTF(playerName);
|
||||||
|
Main.midlet.hiscore.saveScores(dos);
|
||||||
|
dos.flush();
|
||||||
|
options = encode(baos.toByteArray());
|
||||||
|
dos.close();
|
||||||
|
rmsStore.setRecord(1, options, 0, options.length);
|
||||||
|
} catch (InvalidRecordIDException ridex) {
|
||||||
|
try {
|
||||||
|
rmsStore.addRecord(options, 0, options.length);
|
||||||
|
} catch (RecordStoreException ex) {}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rmsStore != null) {
|
||||||
|
try {
|
||||||
|
rmsStore.closeRecordStore();
|
||||||
|
rmsStore = null;
|
||||||
|
} catch (RecordStoreException ex) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Восстановить настройки
|
||||||
|
*/
|
||||||
|
public static void restoreOptions() {
|
||||||
|
try {
|
||||||
|
rmsStore = RecordStore.openRecordStore(rmsName, true);
|
||||||
|
} catch (RecordStoreException ex) {
|
||||||
|
rmsStore = null;
|
||||||
|
}
|
||||||
|
if (rmsStore != null) {
|
||||||
|
try {
|
||||||
|
byte[] data = encode(rmsStore.getRecord(1));
|
||||||
|
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data));
|
||||||
|
firstStart = dis.readBoolean();
|
||||||
|
language = dis.readUTF();
|
||||||
|
lastTableSize = dis.readInt();
|
||||||
|
playerName = dis.readUTF();
|
||||||
|
Main.midlet.hiscore.loadScores(dis);
|
||||||
|
dis.close();
|
||||||
|
} catch (Exception ex) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] encode(byte[] data) {
|
||||||
|
for (int i = 0; i < data.length; i++) {
|
||||||
|
data[i] ^= 119;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
73
src/SoftBar.java
Normal file
73
src/SoftBar.java
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import com.s3d.Camera;
|
||||||
|
import com.s3d.Matrix3D;
|
||||||
|
import com.s3d.Mesh;
|
||||||
|
import javax.microedition.lcdui.Graphics;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* aNNiMON 2012
|
||||||
|
* For more info visit http://annimon.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Софтбар с выбором цвета для заливки
|
||||||
|
* @author aNNiMON
|
||||||
|
*/
|
||||||
|
public class SoftBar {
|
||||||
|
private Matrix3D[] matrix;
|
||||||
|
private Mesh[] mesh;
|
||||||
|
private double[][] rotate;
|
||||||
|
|
||||||
|
public SoftBar() {
|
||||||
|
mesh = new Mesh[Main.MAX_COLORS];
|
||||||
|
matrix = new Matrix3D[Main.MAX_COLORS];
|
||||||
|
rotate = new double[Main.MAX_COLORS][];
|
||||||
|
|
||||||
|
for (int i = 0; i < mesh.length; i++) {
|
||||||
|
mesh[i] = new Box(Main.BOX_SIZE).getBox(Main.COLORS[i]);
|
||||||
|
|
||||||
|
// int x = ((i - mesh.length) / 2) * Main.BOX_SIZE;
|
||||||
|
// mesh[i].move(x, 0, 0);
|
||||||
|
//
|
||||||
|
matrix[i] = new Matrix3D();
|
||||||
|
rotate[i] = new double[] { 0, 0, 0 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paint(Graphics g, byte active) {
|
||||||
|
int h = g.getClipHeight();
|
||||||
|
int tempW = Camera.w;
|
||||||
|
int tempH = Camera.h;
|
||||||
|
|
||||||
|
Camera.w = g.getClipWidth() / mesh.length;
|
||||||
|
Camera.h = h / mesh.length;
|
||||||
|
|
||||||
|
for (int i = 0; i < mesh.length; i++) {
|
||||||
|
matrix[i].unit();
|
||||||
|
|
||||||
|
// Поворачиваем по всем осям
|
||||||
|
matrix[i].xrot(rotate[i][1]);
|
||||||
|
matrix[i].yrot(rotate[i][0]);
|
||||||
|
matrix[i].zrot(rotate[i][2]);
|
||||||
|
|
||||||
|
// Устанавливаем координаты модели
|
||||||
|
matrix[i].translate(0, 0, 550);
|
||||||
|
|
||||||
|
if ((i == active) || (active == -1)) {
|
||||||
|
for (int j = 0; j <= 2; j++) {
|
||||||
|
rotate[i][j] += 5;
|
||||||
|
|
||||||
|
if (rotate[i][j] > 360) {
|
||||||
|
rotate[i][j] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g.translate(Camera.w * i, h - Camera.h - i);
|
||||||
|
mesh[i].paint(g, matrix[i]);
|
||||||
|
g.translate(-Camera.w * i, -(h - Camera.h - i));
|
||||||
|
}
|
||||||
|
|
||||||
|
Camera.w = tempW;
|
||||||
|
Camera.h = tempH;
|
||||||
|
}
|
||||||
|
}
|
24
src/StringEncoder.java
Normal file
24
src/StringEncoder.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
public class StringEncoder {
|
||||||
|
protected static char cp1251[] = {
|
||||||
|
'\u0410', '\u0411', '\u0412', '\u0413', '\u0414', '\u0415', '\u0416', '\u0417', '\u0418', '\u0419', '\u041A',
|
||||||
|
'\u041B', '\u041C', '\u041D', '\u041E', '\u041F', '\u0420', '\u0421', '\u0422', '\u0423', '\u0424', '\u0425',
|
||||||
|
'\u0426', '\u0427', '\u0428', '\u0429', '\u042A', '\u042B', '\u042C', '\u042D', '\u042E', '\u042F', '\u0430',
|
||||||
|
'\u0431', '\u0432', '\u0433', '\u0434', '\u0435', '\u0436', '\u0437', '\u0438', '\u0439', '\u043A', '\u043B',
|
||||||
|
'\u043C', '\u043D', '\u043E', '\u043F', '\u0440', '\u0441', '\u0442', '\u0443', '\u0444', '\u0445', '\u0446',
|
||||||
|
'\u0447', '\u0448', '\u0449', '\u044A', '\u044B', '\u044C', '\u044D', '\u044E', '\u044F'
|
||||||
|
};
|
||||||
|
|
||||||
|
public static char decodeCharCP1251(byte b) {
|
||||||
|
int ich = b & 0xff;
|
||||||
|
|
||||||
|
if (ich == 0xb8) {
|
||||||
|
return 0x0451;
|
||||||
|
} else if (ich == 0xa8) {
|
||||||
|
return 0x0401;
|
||||||
|
} else if (ich >= 0xc0) {
|
||||||
|
return cp1251[ich - 192];
|
||||||
|
}
|
||||||
|
|
||||||
|
return (char) ich;
|
||||||
|
}
|
||||||
|
}
|
53
src/Table.java
Normal file
53
src/Table.java
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import com.s3d.Matrix3D;
|
||||||
|
import com.s3d.Mesh;
|
||||||
|
import javax.microedition.lcdui.Graphics;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* aNNiMON 2012
|
||||||
|
* For more info visit http://annimon.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author aNNiMON
|
||||||
|
*/
|
||||||
|
public class Table {
|
||||||
|
private Mesh[][] mesh;
|
||||||
|
|
||||||
|
public Table(int tableSize) {
|
||||||
|
mesh = new Mesh[tableSize][tableSize];
|
||||||
|
|
||||||
|
for (int i = 0; i < tableSize; i++) {
|
||||||
|
for (int j = 0; j < tableSize; j++) {
|
||||||
|
mesh[i][j] = new Box(Main.BOX_SIZE).getBox(0x00);
|
||||||
|
|
||||||
|
int x = (i - tableSize / 2) * Main.BOX_SIZE;
|
||||||
|
int y = (j - tableSize / 2) * Main.BOX_SIZE;
|
||||||
|
|
||||||
|
mesh[i][j].move(x, -y, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateTable(byte[][] table) {
|
||||||
|
int tableSize = table.length;
|
||||||
|
|
||||||
|
for (int i = 0; i < tableSize; i++) {
|
||||||
|
for (int j = 0; j < tableSize; j++) {
|
||||||
|
byte id = table[i][j];
|
||||||
|
|
||||||
|
mesh[i][j] = Util.setModelColor(mesh[i][j], Main.COLORS[id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paint(Graphics g, Matrix3D matrix) {
|
||||||
|
int tableSize = mesh.length;
|
||||||
|
|
||||||
|
for (int i = 0; i < tableSize; i++) {
|
||||||
|
for (int j = 0; j < tableSize; j++) {
|
||||||
|
mesh[i][j].paint(g, matrix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
138
src/Text3D.java
Normal file
138
src/Text3D.java
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
import com.s3d.Matrix3D;
|
||||||
|
import com.s3d.Mesh;
|
||||||
|
import javax.microedition.lcdui.Font;
|
||||||
|
import javax.microedition.lcdui.Graphics;
|
||||||
|
import javax.microedition.lcdui.Image;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* aNNiMON 2012
|
||||||
|
* For more info visit http://annimon.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Создание и отрисовка 3D текста
|
||||||
|
* @author aNNiMON
|
||||||
|
*/
|
||||||
|
public class Text3D {
|
||||||
|
private Mesh[][] mesh;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Установить текст для отображения в виде 3D
|
||||||
|
* @param text текст
|
||||||
|
*/
|
||||||
|
public void setText(String text) {
|
||||||
|
Image img = getImageFromText(text, 0x00, 0xFFFFFF);
|
||||||
|
int w = img.getWidth();
|
||||||
|
int h = img.getHeight();
|
||||||
|
int[] pix = new int[w * h];
|
||||||
|
|
||||||
|
img.getRGB(pix, 0, w, 0, 0, w, h);
|
||||||
|
img = null;
|
||||||
|
createMeshes(pix, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Отрисовка 3D текста
|
||||||
|
* @param g контекст графики
|
||||||
|
* @param matrix матрица преобразований
|
||||||
|
*/
|
||||||
|
public void paint(Graphics g, Matrix3D matrix) {
|
||||||
|
for (int i = 0; i < mesh.length; i++) {
|
||||||
|
for (int j = 0; j < mesh[i].length; j++) {
|
||||||
|
if (mesh[i][j] == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh[i][j].paint(g, matrix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Создать набор моделей в виде текста
|
||||||
|
* @param pix массив цветов
|
||||||
|
* @param w ширина массива
|
||||||
|
* @param h высота
|
||||||
|
*/
|
||||||
|
private void createMeshes(int[] pix, int w, int h) {
|
||||||
|
mesh = new Mesh[h][w];
|
||||||
|
|
||||||
|
boolean[] medianColor = getMedian(pix);
|
||||||
|
|
||||||
|
for (int i = 0; i < h; i++) {
|
||||||
|
|
||||||
|
// mesh[i] = new Mesh[h];
|
||||||
|
for (int j = 0; j < w; j++) {
|
||||||
|
|
||||||
|
// Пропускаем фоновые пиксели
|
||||||
|
if (!medianColor[i * w + j]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int meshColor = Main.COLORS[Util.random(0, Main.MAX_COLORS)];
|
||||||
|
|
||||||
|
mesh[i][j] = new Box(Main.BOX_SIZE).getBox(meshColor);
|
||||||
|
|
||||||
|
int x = (j - w / 2) * Main.BOX_SIZE;
|
||||||
|
int y = (i - h / 2) * Main.BOX_SIZE;
|
||||||
|
|
||||||
|
mesh[i][j].move(x, -y, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Получить картинку с текстом
|
||||||
|
* @param text текст
|
||||||
|
* @param bgcolor цвет фона
|
||||||
|
* @param textcolor цвет текста
|
||||||
|
* @return картинка с текстом
|
||||||
|
*/
|
||||||
|
private Image getImageFromText(String text, int bgcolor, int textcolor) {
|
||||||
|
Font smallFont = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL);
|
||||||
|
int width = smallFont.stringWidth(text);
|
||||||
|
int height = smallFont.getHeight();
|
||||||
|
Image out = Image.createImage(width, height);
|
||||||
|
Graphics g = out.getGraphics();
|
||||||
|
|
||||||
|
g.setColor(bgcolor);
|
||||||
|
g.fillRect(0, 0, width, height);
|
||||||
|
g.setFont(smallFont);
|
||||||
|
g.setColor(textcolor);
|
||||||
|
g.drawString(text, 0, 0, 20);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Получить черно-белую матрицу по усреднённому цвету
|
||||||
|
* @param pix массив цветов
|
||||||
|
* @return усреднённый цвет
|
||||||
|
*/
|
||||||
|
private boolean[] getMedian(int[] pix) {
|
||||||
|
float size = pix.length;
|
||||||
|
float mr = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < pix.length; i++) {
|
||||||
|
float r = ((pix[i] >> 16) & 0xFF);
|
||||||
|
|
||||||
|
r = r + ((pix[i] >> 8) & 0xFF);
|
||||||
|
r = r + (pix[i] & 0xFF);
|
||||||
|
r /= 3;
|
||||||
|
mr = mr + (r / size);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean[] out = new boolean[pix.length];
|
||||||
|
|
||||||
|
for (int i = 0; i < pix.length; i++) {
|
||||||
|
float r = ((pix[i] >> 16) & 0xFF);
|
||||||
|
|
||||||
|
r = r + ((pix[i] >> 8) & 0xFF);
|
||||||
|
r = r + (pix[i] & 0xFF);
|
||||||
|
r /= 3;
|
||||||
|
out[i] = (r > mr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
182
src/Util.java
Normal file
182
src/Util.java
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
import com.s3d.Mesh;
|
||||||
|
import com.s3d.Face;
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.Vector;
|
||||||
|
import javax.microedition.lcdui.Image;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* aNNiMON 2011
|
||||||
|
* For more info visit http://annimon.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author aNNiMON
|
||||||
|
*/
|
||||||
|
public class Util {
|
||||||
|
|
||||||
|
private static final Random rnd = new Random();
|
||||||
|
|
||||||
|
/* Получить случайное значение в промежутке (from..to) */
|
||||||
|
public static int random(int from, int to) {
|
||||||
|
return rnd.nextInt(to - from) + from;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Установить цвет модели mesh
|
||||||
|
* @param mesh модель, в которой нужно изменить цвет
|
||||||
|
* @param color цвет в формате RGB
|
||||||
|
* @return модель с изменённым цветом
|
||||||
|
*/
|
||||||
|
public static Mesh setModelColor(Mesh mesh, int color) {
|
||||||
|
int size = mesh.faces.size();
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
Face face = (Face) mesh.faces.elementAt(i);
|
||||||
|
|
||||||
|
face.color = color;
|
||||||
|
mesh.faces.setElementAt(face, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Получить список доступных языков
|
||||||
|
* @param path путь к файлу ресурсов
|
||||||
|
* @return массив строк
|
||||||
|
*/
|
||||||
|
public static String[] getLanguages(String path) {
|
||||||
|
String[] lines = splitString(getText(path, false), " ");
|
||||||
|
for (int i = 0; i < lines.length; i++) {
|
||||||
|
lines[i] = lines[i].trim().toLowerCase();
|
||||||
|
}
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Открыть текст из файла ресурсов
|
||||||
|
* @param path путь к файл
|
||||||
|
* @param protect true - файл с защитой
|
||||||
|
* @return текст
|
||||||
|
*/
|
||||||
|
public static String getText(String path, boolean protect) {
|
||||||
|
DataInputStream dis = new DataInputStream(Runtime.getRuntime().getClass().getResourceAsStream("/"+path));
|
||||||
|
StringBuffer strBuff = new StringBuffer();
|
||||||
|
try {
|
||||||
|
int ch;
|
||||||
|
while ((ch = dis.read()) != -1) {
|
||||||
|
byte bt = (byte) ch;
|
||||||
|
if (protect) bt = (byte) (ch ^ 119);
|
||||||
|
strBuff.append(StringEncoder.decodeCharCP1251(bt));
|
||||||
|
}
|
||||||
|
|
||||||
|
dis.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return strBuff.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Разделение строки на массив подстрок
|
||||||
|
* @param str исходная строка
|
||||||
|
* @param delim строка-разделитель
|
||||||
|
* @return массив подстрок, разбитых по разделителю
|
||||||
|
*/
|
||||||
|
public static String[] splitString(String str, String delim) {
|
||||||
|
if ((str.length() == 0) || (delim.length() == 0)) {
|
||||||
|
return new String[]{str};
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] s;
|
||||||
|
Vector v = new Vector();
|
||||||
|
int pos = 0;
|
||||||
|
int newpos = str.indexOf(delim, 0);
|
||||||
|
|
||||||
|
while (newpos != -1) {
|
||||||
|
v.addElement(str.substring(pos, newpos));
|
||||||
|
pos = newpos + delim.length();
|
||||||
|
newpos = str.indexOf(delim, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
v.addElement(str.substring(pos));
|
||||||
|
s = new String[v.size()];
|
||||||
|
v.copyInto(s);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Image smooth(Image img, int blurHor, int blurVer) {
|
||||||
|
int w = img.getWidth();
|
||||||
|
int h = img.getHeight();
|
||||||
|
int[] pix = new int[w * h];
|
||||||
|
|
||||||
|
img.getRGB(pix, 0, w, 0, 0, w, h);
|
||||||
|
|
||||||
|
int[] pixel = new int[pix.length];
|
||||||
|
|
||||||
|
pixel = BoxBlur(pix, pixel, w, h, blurHor);
|
||||||
|
pix = BoxBlur(pixel, pix, h, w, blurVer);
|
||||||
|
|
||||||
|
return Image.createRGBImage(pix, w, h, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int[] BoxBlur(int[] in, int[] out, int width, int height, int radius) {
|
||||||
|
if (radius <= 0) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
int widthMinus1 = width - 1;
|
||||||
|
int tableSize = 2 * radius + 1;
|
||||||
|
int divideLength = 256 * tableSize;
|
||||||
|
int[] divide = new int[divideLength];
|
||||||
|
|
||||||
|
for (int i = 0; i < divideLength; i++) {
|
||||||
|
divide[i] = i / tableSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
int inIndex = 0;
|
||||||
|
|
||||||
|
for (int y = 0; y < height; y++) {
|
||||||
|
int outIndex = y;
|
||||||
|
int tr = 0, tg = 0, tb = 0;
|
||||||
|
|
||||||
|
for (int i = -radius; i <= radius; i++) {
|
||||||
|
int rgb = in[inIndex + clamp(i, 0, widthMinus1)];
|
||||||
|
|
||||||
|
tr += (rgb >> 16) & 0xff;
|
||||||
|
tg += (rgb >> 8) & 0xff;
|
||||||
|
tb += rgb & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int x = 0; x < width; x++) {
|
||||||
|
out[outIndex] = (255 << 24) | (divide[tr] << 16) | (divide[tg] << 8) | divide[tb];
|
||||||
|
|
||||||
|
int i1 = x + radius + 1;
|
||||||
|
if (i1 > widthMinus1) i1 = widthMinus1;
|
||||||
|
|
||||||
|
int i2 = x - radius;
|
||||||
|
if (i2 < 0) i2 = 0;
|
||||||
|
|
||||||
|
int rgb1 = in[inIndex + i1];
|
||||||
|
int rgb2 = in[inIndex + i2];
|
||||||
|
|
||||||
|
tr += ((rgb1 & 0xff0000) - (rgb2 & 0xff0000)) >> 16;
|
||||||
|
tg += ((rgb1 & 0xff00) - (rgb2 & 0xff00)) >> 8;
|
||||||
|
tb += (rgb1 & 0xff) - (rgb2 & 0xff);
|
||||||
|
outIndex += height;
|
||||||
|
}
|
||||||
|
|
||||||
|
inIndex += width;
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int clamp(int x, int a, int b) {
|
||||||
|
return (x < a) ? a : (x > b) ? b : x;
|
||||||
|
}
|
||||||
|
}
|
BIN
src/about.en
Normal file
BIN
src/about.en
Normal file
Binary file not shown.
BIN
src/about.ru
Normal file
BIN
src/about.ru
Normal file
Binary file not shown.
9
src/com/s3d/Camera.java
Normal file
9
src/com/s3d/Camera.java
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package com.s3d;
|
||||||
|
|
||||||
|
|
||||||
|
public class Camera {
|
||||||
|
|
||||||
|
public static int w = 132;
|
||||||
|
public static int h = 176;
|
||||||
|
public static int limit = 2000;
|
||||||
|
}
|
19
src/com/s3d/Face.java
Normal file
19
src/com/s3d/Face.java
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package com.s3d;
|
||||||
|
|
||||||
|
import javax.microedition.lcdui.Graphics;
|
||||||
|
|
||||||
|
public abstract class Face {
|
||||||
|
|
||||||
|
public int color;
|
||||||
|
|
||||||
|
public abstract int getS();
|
||||||
|
|
||||||
|
public abstract void paint(Graphics g, boolean flag);
|
||||||
|
|
||||||
|
public abstract void paint(Graphics g, int i);
|
||||||
|
|
||||||
|
public abstract void move(int i, int j, int k);
|
||||||
|
|
||||||
|
public abstract void setMatrix(Matrix3D matrix3d);
|
||||||
|
|
||||||
|
}
|
81
src/com/s3d/Matrix3D.java
Normal file
81
src/com/s3d/Matrix3D.java
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
package com.s3d;
|
||||||
|
|
||||||
|
|
||||||
|
public class Matrix3D {
|
||||||
|
|
||||||
|
float xx, xy, xz, xo;
|
||||||
|
float yx, yy, yz, yo;
|
||||||
|
float zx, zy, zz, zo;
|
||||||
|
|
||||||
|
public Matrix3D() {
|
||||||
|
xx = 1.0F;
|
||||||
|
yy = 1.0F;
|
||||||
|
zz = 1.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void translate(float x, float y, float z) {
|
||||||
|
xo += x;
|
||||||
|
yo += y;
|
||||||
|
zo += z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void yrot(double d) {
|
||||||
|
d *= 0.017453292519943295D;
|
||||||
|
double d1 = Math.cos(d);
|
||||||
|
double d2 = Math.sin(d);
|
||||||
|
float f0 = (float) (xx * d1 + zx * d2);
|
||||||
|
float f1 = (float) (xy * d1 + zy * d2);
|
||||||
|
float f2 = (float) (xz * d1 + zz * d2);
|
||||||
|
float f3 = (float) (xo * d1 + zo * d2);
|
||||||
|
zx = (float) (zx * d1 - xx * d2);
|
||||||
|
zy = (float) (zy * d1 - xy * d2);
|
||||||
|
zz = (float) (zz * d1 - xz * d2);
|
||||||
|
zo = (float) (zo * d1 - xo * d2);
|
||||||
|
xo = f3;
|
||||||
|
xx = f0;
|
||||||
|
xy = f1;
|
||||||
|
xz = f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void xrot(double d) {
|
||||||
|
d *= 0.017453292519943295D;
|
||||||
|
double d1 = Math.cos(d);
|
||||||
|
double d2 = Math.sin(d);
|
||||||
|
float f0 = (float) (yx * d1 + zx * d2);
|
||||||
|
float f1 = (float) (yy * d1 + zy * d2);
|
||||||
|
float f2 = (float) (yz * d1 + zz * d2);
|
||||||
|
float f3 = (float) (yo * d1 + zo * d2);
|
||||||
|
zx = (float) (zx * d1 - yx * d2);
|
||||||
|
zy = (float) (zy * d1 - yy * d2);
|
||||||
|
zz = (float) (zz * d1 - yz * d2);
|
||||||
|
zo = (float) (zo * d1 - yo * d2);
|
||||||
|
yo = f3;
|
||||||
|
yx = f0;
|
||||||
|
yy = f1;
|
||||||
|
yz = f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void zrot(double d) {
|
||||||
|
d *= 0.017453292519943295D;
|
||||||
|
double d1 = Math.cos(d);
|
||||||
|
double d2 = Math.sin(d);
|
||||||
|
float f0 = (float) (yx * d1 + xx * d2);
|
||||||
|
float f1 = (float) (yy * d1 + xy * d2);
|
||||||
|
float f2 = (float) (yz * d1 + xz * d2);
|
||||||
|
float f3 = (float) (yo * d1 + xo * d2);
|
||||||
|
xx = (float) (xx * d1 - yx * d2);
|
||||||
|
xy = (float) (xy * d1 - yy * d2);
|
||||||
|
xz = (float) (xz * d1 - yz * d2);
|
||||||
|
xo = (float) (xo * d1 - yo * d2);
|
||||||
|
yo = f3;
|
||||||
|
yx = f0;
|
||||||
|
yy = f1;
|
||||||
|
yz = f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unit() {
|
||||||
|
xo = 0; xx = 1; xy = 0; xz = 0;
|
||||||
|
yo = 0; yx = 0; yy = 1; yz = 0;
|
||||||
|
zo = 0; zx = 0; zy = 0; zz = 1;
|
||||||
|
}
|
||||||
|
}
|
64
src/com/s3d/Mesh.java
Normal file
64
src/com/s3d/Mesh.java
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package com.s3d;
|
||||||
|
|
||||||
|
import java.util.Vector;
|
||||||
|
import javax.microedition.lcdui.Graphics;
|
||||||
|
|
||||||
|
public class Mesh {
|
||||||
|
|
||||||
|
public Vector faces;
|
||||||
|
|
||||||
|
private static final int[] d = {
|
||||||
|
1, 4, 10, 23, 57, 145, 356, 911, 1968, 4711, 11969, 27901,
|
||||||
|
84801, 213331, 543749, 1355339, 3501671, 8810089, 21521774,
|
||||||
|
58548857, 157840433, 410151271, 0x436f7079, 2147483647
|
||||||
|
};
|
||||||
|
|
||||||
|
public Mesh() {
|
||||||
|
faces = new Vector();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paint(Graphics g, Matrix3D matrix3d) {
|
||||||
|
if (faces.isEmpty() || g == null || matrix3d == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sort(faces);
|
||||||
|
for (int i = faces.size() - 1; i >= 0; i--) {
|
||||||
|
//try {
|
||||||
|
Face face = (Face) faces.elementAt(i);
|
||||||
|
face.setMatrix(matrix3d);
|
||||||
|
face.paint(g, true);
|
||||||
|
//} catch (Exception exception) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addFace(Face face) {
|
||||||
|
faces.addElement(face);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void move(int i, int j, int k) {
|
||||||
|
for (int l = 0; l < faces.size(); l++) {
|
||||||
|
((Face) faces.elementAt(l)).move(i, j, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sort(Vector vector) {
|
||||||
|
int l = 0;
|
||||||
|
int i1 = vector.size();
|
||||||
|
while (d[l] < i1) l++;
|
||||||
|
//for (i1 = vector.size(); d[l] < i1; l++) {}
|
||||||
|
while (--l >= 0) {
|
||||||
|
int k = d[l];
|
||||||
|
for (int i = k; i < i1; i++) {
|
||||||
|
int j = i;
|
||||||
|
Face face = (Face) vector.elementAt(i);
|
||||||
|
for (int j1 = face.getS(); j >= k && ((Face) vector.elementAt(j - k)).getS() > j1; j -= k) {
|
||||||
|
vector.setElementAt(vector.elementAt(j - k), j);
|
||||||
|
}
|
||||||
|
vector.setElementAt(face, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
106
src/com/s3d/Square.java
Normal file
106
src/com/s3d/Square.java
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
package com.s3d;
|
||||||
|
|
||||||
|
import javax.microedition.lcdui.Graphics;
|
||||||
|
|
||||||
|
public class Square extends Face {
|
||||||
|
|
||||||
|
private Vertex v1, v2, v3, v4;
|
||||||
|
private float nx, ny, nz;
|
||||||
|
private float rnz;
|
||||||
|
private float k;
|
||||||
|
|
||||||
|
public Square(Vertex vertex, Vertex vertex1, Vertex vertex2, Vertex vertex3, int color) {
|
||||||
|
v1 = vertex3;
|
||||||
|
v2 = vertex1;
|
||||||
|
v3 = vertex;
|
||||||
|
super.color = color;
|
||||||
|
float f = (v1.y - v2.y) * (v2.z - v3.z) - (v1.z - v2.z) * (v2.y - v3.y);
|
||||||
|
float f1 = (v1.z - v2.z) * (v2.x - v3.x) - (v1.x - v2.x) * (v2.z - v3.z);
|
||||||
|
float f2 = (v1.x - v2.x) * (v2.y - v3.y) - (v1.y - v2.y) * (v2.x - v3.x);
|
||||||
|
double d = Math.sqrt(f * f + f1 * f1 + f2 * f2);
|
||||||
|
f = (float) (f / d);
|
||||||
|
f1 = (float) (f1 / d);
|
||||||
|
f2 = (float) (f2 / d);
|
||||||
|
v1 = vertex3;
|
||||||
|
v2 = vertex2;
|
||||||
|
v3 = vertex1;
|
||||||
|
float f3 = (v1.y - v2.y) * (v2.z - v3.z) - (v1.z - v2.z) * (v2.y - v3.y);
|
||||||
|
float f4 = (v1.z - v2.z) * (v2.x - v3.x) - (v1.x - v2.x) * (v2.z - v3.z);
|
||||||
|
float f5 = (v1.x - v2.x) * (v2.y - v3.y) - (v1.y - v2.y) * (v2.x - v3.x);
|
||||||
|
d = Math.sqrt(f3 * f3 + f4 * f4 + f5 * f5);
|
||||||
|
f3 = (float) (f3 / d);
|
||||||
|
f4 = (float) (f4 / d);
|
||||||
|
f5 = (float) (f5 / d);
|
||||||
|
nx = (f + f3) / 2f;
|
||||||
|
ny = (f1 + f4) / 2f;
|
||||||
|
rnz = nz = (f2 + f5) / 2f;
|
||||||
|
v1 = vertex;
|
||||||
|
v2 = vertex1;
|
||||||
|
v3 = vertex2;
|
||||||
|
v4 = vertex3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getS() {
|
||||||
|
return (v1.zc + v2.zc + v3.zc + v4.zc) / 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paint(Graphics graphics, boolean flag) {
|
||||||
|
if (flag) {
|
||||||
|
k = rnz;
|
||||||
|
if (k > 0f) k = -k;
|
||||||
|
if (k < -1f) k = -1f;
|
||||||
|
int r = (super.color >> 16) & 0xff;
|
||||||
|
int g = (super.color >> 8) & 0xff;
|
||||||
|
int b = super.color & 0xff;
|
||||||
|
r = (int) (r * -k);
|
||||||
|
g = (int) (g * -k);
|
||||||
|
b = (int) (b * -k);
|
||||||
|
paint(graphics, (r << 16) | (g << 8) | b);
|
||||||
|
} else {
|
||||||
|
paint(graphics, super.color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paint(Graphics g, int i) {
|
||||||
|
if (topaint()) {
|
||||||
|
g.setColor(i);
|
||||||
|
g.fillTriangle(v1.sx, v1.sy, v2.sx, v2.sy, v3.sx, v3.sy);
|
||||||
|
g.fillTriangle(v1.sx, v1.sy, v3.sx, v3.sy, v4.sx, v4.sy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMatrix(Matrix3D matrix3d) {
|
||||||
|
v1.setMatrix(matrix3d);
|
||||||
|
v2.setMatrix(matrix3d);
|
||||||
|
v3.setMatrix(matrix3d);
|
||||||
|
v4.setMatrix(matrix3d);
|
||||||
|
rnz = nx * matrix3d.zx + ny * matrix3d.zy + nz * matrix3d.zz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void move(int i, int j, int l) {
|
||||||
|
v1.move(i, j, l);
|
||||||
|
v2.move(i, j, l);
|
||||||
|
v3.move(i, j, l);
|
||||||
|
v4.move(i, j, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean topaint() {
|
||||||
|
if (v1.zc < 0 || v2.zc < 0 || v3.zc < 0 || v4.zc < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (v1.zc > Camera.limit && v2.zc > Camera.limit && v3.zc > Camera.limit && v4.zc > Camera.limit) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (v1.sx <= 0 && v2.sx <= 0 && v3.sx <= 0 && v4.sx <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (v1.sx >= Camera.w && v2.sx >= Camera.w && v3.sx >= Camera.w && v4.sx >= Camera.w) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (v1.sy <= 0 && v2.sy <= 0 && v3.sy <= 0 && v4.sy <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return v1.sy < Camera.h || v2.sy < Camera.h || v3.sy < Camera.h || v4.sy < Camera.h;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
42
src/com/s3d/Vertex.java
Normal file
42
src/com/s3d/Vertex.java
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package com.s3d;
|
||||||
|
|
||||||
|
public class Vertex {
|
||||||
|
|
||||||
|
private static final int perx = 300;
|
||||||
|
private static final int pery = 300;
|
||||||
|
|
||||||
|
public int sx, sy;
|
||||||
|
public int zc;
|
||||||
|
public int x, y, z;
|
||||||
|
private int xc, yc;
|
||||||
|
|
||||||
|
public Vertex(int i, int j, int k) {
|
||||||
|
x = i;
|
||||||
|
y = j;
|
||||||
|
z = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMatrix(Matrix3D matrix3d) {
|
||||||
|
xc = (int) (x * matrix3d.xx + y * matrix3d.xy + z * matrix3d.xz);
|
||||||
|
yc = (int) (x * matrix3d.yx + y * matrix3d.yy + z * matrix3d.yz);
|
||||||
|
zc = (int) (x * matrix3d.zx + y * matrix3d.zy + z * matrix3d.zz);
|
||||||
|
xc += matrix3d.xo;
|
||||||
|
yc += matrix3d.yo;
|
||||||
|
zc += matrix3d.zo;
|
||||||
|
to2d();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void move(int i, int j, int k) {
|
||||||
|
x += i;
|
||||||
|
y += j;
|
||||||
|
z += k;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void to2d() {
|
||||||
|
int k = (zc <= 0) ? -1 : zc;
|
||||||
|
int i = (xc * perx) / k;
|
||||||
|
int j = (yc * pery) / k;
|
||||||
|
sx = Camera.w / 2 + i;
|
||||||
|
sy = Camera.h / 2 - j;
|
||||||
|
}
|
||||||
|
}
|
17
src/en.lang
Normal file
17
src/en.lang
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
Start
|
||||||
|
Options
|
||||||
|
High score
|
||||||
|
Help
|
||||||
|
Exit
|
||||||
|
Table size
|
||||||
|
Language
|
||||||
|
Reset scores
|
||||||
|
Back
|
||||||
|
Position
|
||||||
|
Rotate
|
||||||
|
Game Over
|
||||||
|
Moves:
|
||||||
|
New high score:
|
||||||
|
Enter your name
|
||||||
|
Ok
|
||||||
|
Unknown
|
BIN
src/icon.png
Normal file
BIN
src/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 874 B |
1
src/langs.txt
Normal file
1
src/langs.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
en ru
|
17
src/ru.lang
Normal file
17
src/ru.lang
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
Старт
|
||||||
|
Настройки
|
||||||
|
Рекорды
|
||||||
|
Помощь
|
||||||
|
Выход
|
||||||
|
Размер поля
|
||||||
|
Язык
|
||||||
|
Сброс
|
||||||
|
Назад
|
||||||
|
Позиция
|
||||||
|
Поворот
|
||||||
|
Игра окончена
|
||||||
|
Ходов:
|
||||||
|
Новый рекорд:
|
||||||
|
Введите имя
|
||||||
|
Ok
|
||||||
|
Аноним
|
Loading…
Reference in New Issue
Block a user