This commit is contained in:
Victor 2018-11-15 00:00:52 +02:00
parent 52f4c7379e
commit f491889b36
11 changed files with 778 additions and 32 deletions

215
src/About.java Normal file
View File

@ -0,0 +1,215 @@
/*
* aNNiMON 2010
* For more info visit http://annimon.com/
*/
/*
* На основе класса MultiLineText от А.С. Ледкова
* www.mobilab.ru
*/
import com.emos.ui.ESkin;
import com.emos.ui.StringEncoder;
import java.io.DataInputStream;
import java.util.Vector;
import javax.microedition.lcdui.*;
public class About extends Canvas {
private final String path = "about.ru";
private Font def, fnt;
private int fontHeight, defHeight;
private String str; //текст
private int w, h; //размеры
private int mh; //Размер ограничивающего прямоугольника;
private int y0; //Положение верхнего края текста
private int dy; //Шаг при прокрутке текста
private int textheight; //Общая высота текста
private Vector strLines;
public About() {
setFullScreenMode(true);
w = getWidth();
h = getHeight();
str = getText(path);
fnt = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD, Font.SIZE_SMALL);
def = Font.getDefaultFont();
fontHeight = fnt.getHeight()+2;
dy = defHeight = def.getHeight()+2;
//
//15;
mh = h - fontHeight - 1;
SetTextPar();
}
protected void paint(Graphics g) {
int hc = h/2;
ESkin.drawVGradient (g, ESkin.wBack, ESkin.wBack2, 0,0, w,hc);
ESkin.drawVGradient (g, ESkin.wBack2, ESkin.wBack, 0,hc,w,h-hc);
ESkin.drawHGradient(g, ESkin.wTitle, ESkin.lBack, 0, 0, w, fontHeight);
g.setFont(fnt);
g.setColor(ESkin.wTitle);
g.drawString("RayCanvas", w/2, 1, 17);
g.setFont(def);
g.setClip(0, fontHeight+1, w, mh);
int y1 = y0;
for (int i = 0; i < strLines.size(); i++) {
if ((y1 + defHeight) > 0) {
g.drawString(strLines.elementAt(i).toString(), 1, fontHeight + 5 + y1, Graphics.LEFT | Graphics.TOP);
}
y1 = y1 + defHeight;
if (y1 > mh) {
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)
Main.midlet.dsp.setCurrent(Main.midlet.mn);
repaint();
}
protected void pointerPressed(int x, int y) {
int w3 = w/3;
int h3 = h/3;
if(y<h3 && (x>w3 && x<(w-w3))) keyPressed(UP);
else if(y>(h-h3) && (x>w3 && x<(w-w3))) keyPressed(DOWN);
if(x<w3 && (y>h3 && y<(h-h3))) keyPressed(LEFT);
else if(x>(w-w3) && (y>h3 && y<(h-h3))) keyPressed(RIGHT);
else if(x<w3 && y>(h-h3)) keyPressed(-6);
else if(x>(w-w3) && y>(h-h3)) keyPressed(-7);
else if( (x>w3 && x<(w-w3)) && (y>h3 && y<(h-h3)) ) keyPressed(FIRE);
}
private void SetTextPar() {
//Разбиваем строку на массив строк
strLines = null;
strLines = new Vector();
String[] arr = splitString(str, "\n");
for(int i=0; i<arr.length; i++) {
String substr = arr[i];
int i0 = 0, space = 0, in = 0, j = 0, jw = 0; //Смещение от начала строки
int imax = substr.length(); //Длина строки
boolean isexit = true;
y0 = 0;
while (isexit) {
space = substr.indexOf(" ", i0 + 1);
if (space <= i0) {
space = imax;
isexit = false;
}
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 String getText(String path) {
DataInputStream dis = new DataInputStream(getClass().getResourceAsStream(path));
StringBuffer strBuff = new StringBuffer();
int ch = 0;
try {
while ((ch = dis.read()) != -1) {
strBuff.append(StringEncoder.decodeCharCP1251((byte)ch));
}
dis.close();
} catch (Exception e) {e.printStackTrace();}
return strBuff.toString();
}
private void MoveDown() {
if (textheight > mh) {
y0 = y0 - dy;
if (mh - y0 > textheight) {
y0 = mh - textheight;
}
}
}
private void MoveUp() {
if (textheight > mh) {
y0 = y0 + dy;
if (y0 > 0) {
y0 = 0;
}
}
}
private void PageUp() {
if (textheight > mh) {
y0 = y0 + mh;
if (y0 > 0) {
y0 = 0;
}
}
}
private void PageDown() {
if (textheight > mh) {
y0 = y0 - mh;
if (mh - y0 > textheight) {
y0 = mh - textheight;
}
}
}
private String[] splitString(String str, String delim) {
if (str.equals("") || delim == null || 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;
}
}

View File

@ -55,6 +55,8 @@ public class Grid {
// the entrance to the maze is at (0,1). // the entrance to the maze is at (0,1).
mySquares[0][1] = 0; mySquares[0][1] = 0;
createMaze(); createMaze();
mySquares[mySquares.length-2][mySquares[0].length-4] = 5;
mySquares[mySquares.length-2][mySquares[0].length-2] = 5;
mySquares[mySquares.length-2][mySquares[0].length-3] = 5; mySquares[mySquares.length-2][mySquares[0].length-3] = 5;
mySquares[mySquares.length-1][mySquares[0].length-3] = 5; mySquares[mySquares.length-1][mySquares[0].length-3] = 5;
} }
@ -197,7 +199,7 @@ public class Grid {
* @param upper the upper bound for the random int. * @param upper the upper bound for the random int.
* @return a random non-negative int less than the bound upper. * @return a random non-negative int less than the bound upper.
*/ */
private int getRandomInt(int upper) { public int getRandomInt(int upper) {
int retVal = myRandom.nextInt() % upper; int retVal = myRandom.nextInt() % upper;
if (retVal < 0) { if (retVal < 0) {
retVal += upper; retVal += upper;

View File

@ -6,7 +6,8 @@ public class Main extends MIDlet {
public Display dsp; public Display dsp;
public static Main midlet; public static Main midlet;
private RayCanvas canvas; public Menu mn;
public Main() { public Main() {
dsp = Display.getDisplay(Main.this); dsp = Display.getDisplay(Main.this);
@ -14,9 +15,8 @@ public class Main extends MIDlet {
} }
public void startApp() { public void startApp() {
canvas = new RayCanvas(); mn = new Menu();
dsp.vibrate(1000); dsp.setCurrent(mn);
dsp.setCurrent(canvas);
} }
public void pauseApp() { public void pauseApp() {

94
src/Menu.java Normal file
View File

@ -0,0 +1,94 @@
/*
* aNNiMON 2011
* For more info visit http://annimon.com/
*/
import com.emos.ui.*;
import java.util.Random;
import javax.microedition.lcdui.Graphics;
/**
*
* @author aNNiMON
*/
public class Menu extends EWindow {
private String[] m1;
private int fh, cu, yy, d;
private Random rnd;
private long ty;
private RayCanvas ray;
public Menu() {
super("RayCanvas");
m1 = new String[] {
"Начать",
"Об игре",
"Выход",
};
rnd = new Random();
ray = new RayCanvas();
ESkin e = new ESkin(rnd.nextInt()%0xFFFFFF);
fh = EConst.mainFont.getHeight()+2;
yy = cu = 0;
d = hh/6;
}
protected void showNotify() {
ESkin e = new ESkin(rnd.nextInt()%0xFFFFFF);
}
public void paint(Graphics g, int w, int h) {
int hc = d+yy+cu*fh;
g.setFont(EConst.mainFont);
for (int i = 0;i<m1.length;i++) {
if (i==cu) continue;
g.setColor(ESkin.wBack2);
g.drawString(m1[i], w/2, d+i*fh, Graphics.HCENTER| Graphics.TOP);
}
g.setColor(ESkin.wBack);
g.fillRoundRect(5, hc, w-10, fh, 15, 15);
g.setColor(ESkin.wTitle);
g.drawString(m1[cu], w/2, d+cu*fh, Graphics.HCENTER| Graphics.TOP);
if(yy<0) yy+=2;
else if(yy>0) yy-=2;
if(yy>1 || yy<-1) redraw();
}
public void keyEvent(int key, byte state) {
if(state!=RELEASED) {
int ga = getGameAction(key);
if (ga==UP && cu>0) {cu--; yy=fh;}
else if (ga==DOWN && cu<m1.length-1) {cu++; yy=-fh;}
else if (ga==FIRE || key==-6 || key==-7) getM1Code(cu);
}
redraw();
}
private void getM1Code(int nfct) {
if(nfct==0) Main.midlet.dsp.setCurrent(ray);
else if(nfct==1) Main.midlet.dsp.setCurrent(new About());
else if(nfct==2) Main.midlet.destroyApp(true);
}
protected void pointerPressed(int x, int y) {
int hc = d+fh;
int w3 = w/3;
int h3 = h/3;
if(x<w3 && y>(h-h3)) keyEvent(-6, PRESSED);
else if(x>(w-w3) && y>(h-h3)) keyEvent(-7, PRESSED);
else{
int cu1=cu;
y-=hc;
if(y>0 && y<m1.length*fh) {
cu=y/fh;
}
if(System.currentTimeMillis()-ty<700 && cu1==cu) getM1Code(cu);
ty = System.currentTimeMillis();
}
redraw();
}
}

View File

@ -6,15 +6,17 @@ public class RayCanvas extends Canvas {// implements Runnable {
private Keyboard keyb; private Keyboard keyb;
private Grid grid; private Grid grid;
private int gluk; private byte gluk;
private Image pr; private Image pr;
//Motion Blur
private int[][] colors = new int[][] { private int[][] colors = new int[][] {
{0xcccc44, 0x444444, 0x333333, 0x222222, 0x111111},//gluk0 {0xcccc44, 0x444444, 0x333333, 0x222222, 0x111111},//gluk0
{0xcccc44, 0xaaaaaa, 0x888888, 0x555555, 0xcccccc},//gluk1 {0xcccc44, 0xaaaaaa, 0x888888, 0x555555, 0xcccccc},//gluk1
{0xcccc44, 0xcc4444, 0x44cc44, 0x4444cc, 0xcccccc},//gluk2 {0xcccc44, 0xcc4444, 0x44cc44, 0x4444cc, 0xcccccc},//gluk2
{0xcccc44, 0xaa54a4, 0x803488, 0x5a5055, 0xc2087c} //gluk3 {0xcccc44, 0xaa54a4, 0x803488, 0x5a5055, 0xc2087c} //gluk3
}; };
private int[] glukstep;
private byte[] glukmode;
private double posX, posY; //x and y start position private double posX, posY; //x and y start position
private double dirX, dirY; //initial direction vector private double dirX, dirY; //initial direction vector
private double planeX, planeY; //the 2d raycaster version of camera plane private double planeX, planeY; //the 2d raycaster version of camera plane
@ -27,12 +29,12 @@ public class RayCanvas extends Canvas {// implements Runnable {
setFullScreenMode(true); setFullScreenMode(true);
w = getWidth(); w = getWidth();
h = getHeight(); h = getHeight();
grid = new Grid(25); glukstep = new int[colors.length];
grid.newMaze(); glukmode = new byte[colors.length];
restart(true);
end = showUI = false;
posX = 1; showUI = false;
posY = 1.1;
dirX = -1; dirX = -1;
lastTime = 0; lastTime = 0;
dirY = planeX = 0; dirY = planeX = 0;
@ -49,7 +51,7 @@ public class RayCanvas extends Canvas {// implements Runnable {
if(key == KEY_STAR) showUI = !showUI; if(key == KEY_STAR) showUI = !showUI;
else if (key == -6) restart(false); else if (key == -6) restart(false);
else if (key == -7 || (end && getGameAction(key)==FIRE)) restart(true); else if (key == -7 || (end && getGameAction(key)==FIRE)) restart(true);
else if (key == KEY_NUM0) Main.midlet.destroyApp(true); else if (key == KEY_NUM0) Main.midlet.dsp.setCurrent(Main.midlet.mn);
else if(showUI && key == KEY_NUM1) uiSize(-1); else if(showUI && key == KEY_NUM1) uiSize(-1);
else if(showUI && key == KEY_NUM3) uiSize(1); else if(showUI && key == KEY_NUM3) uiSize(1);
else keyb.onPressed(key, getGameAction(key)); else keyb.onPressed(key, getGameAction(key));
@ -61,19 +63,29 @@ public class RayCanvas extends Canvas {// implements Runnable {
public void paint(Graphics g) { public void paint(Graphics g) {
long thisTime = System.currentTimeMillis(); // òåêóùåå âðåìÿ long thisTime = System.currentTimeMillis(); // òåêóùåå âðåìÿ
int dTime = (int) (thisTime - lastTime);// âðåìÿ, ïðîøåäøåå ñ ïðîøëîãî êàäðà double dTime = (thisTime - lastTime)/1000d;// âðåìÿ, ïðîøåäøåå ñ ïðîøëîãî êàäðà
lastTime = thisTime; lastTime = thisTime;
g.setColor(0); if(glukmode[0]==1 && gluk==3){// && gluk==2) {
int[] pixelArray = new int[w * h];
for (int io = 0; io < pixelArray.length; io++) {
pixelArray[io] = 0x30000000;
}
g.drawRGB(pixelArray, 0, w, 0, 0, w, h, true);
}else{
if(glukmode[0]==3 && gluk==1)
g.setColor(0xFFFFFF);
else g.setColor(0);
g.fillRect(0, 0, w, h); g.fillRect(0, 0, w, h);
}
int yy = grid.width/3; int yy = grid.width/3;
if (posX < yy) gluk = 1; if (posX < yy) gluk = glukmode[1];
else if(posX > yy && posX < yy*2) gluk = 2; else if(posX > yy && posX < yy*2) gluk = glukmode[2];
else if (posX > yy*2 && posX < grid.width) gluk = 3; else if (posX > yy*2 && posX < grid.width) gluk = glukmode[3];
else if ((posX > (yy+yy/2)) && posY < (grid.height/2)) gluk = 0; else if ((posX > (yy+yy/2)) && posY < (grid.height/2)) gluk = glukmode[0];
for (int x = 0; x < w; x+=1) { for (int x = 0; x < w; x+=glukstep[gluk]) {
//calculate ray position and direction //calculate ray position and direction
double cameraX = 2 * x / (double) w - 1; //x-coordinate in camera space double cameraX = 2 * x / (double) w - 1; //x-coordinate in camera space
double rayPosX = posX; double rayPosX = posX;
@ -149,14 +161,13 @@ public class RayCanvas extends Canvas {// implements Runnable {
int drawEnd = lineHeight / 2 + h / 2; int drawEnd = lineHeight / 2 + h / 2;
if (drawEnd >= h) drawEnd = h - 1; if (drawEnd >= h) drawEnd = h - 1;
g.drawImage(pr, w / 2, h / 2, 3);
//choose wall color //choose wall color
int color = 0; int color = 0;
try { try {
color = colors[gluk][getCell(mapX, mapY)]; color = colors[gluk][getCell(mapX, mapY)];
//give x and y sides different brightness //give x and y sides different brightness
if (side == 1) color -= 0x333333; if (side == 1) color /= 2;
} catch (Exception e) { } catch (Exception e) {
color = 0xcccc44; color = 0xcccc44;
} }
@ -168,8 +179,8 @@ public class RayCanvas extends Canvas {// implements Runnable {
} }
//speed modifiers //speed modifiers
double moveSpeed = (((double) dTime) / 1000) * 5.0; //the constant value is in squares/second double moveSpeed = dTime * 5.0; //the constant value is in squares/second
double rotSpeed = (((double) dTime) / 1000) * 3.0; //the constant value is in radians/second double rotSpeed = dTime * 3.0; //the constant value is in radians/second
//move forward if no wall in front of you //move forward if no wall in front of you
if (keyb.getKeyState(UP)) { if (keyb.getKeyState(UP)) {
@ -179,9 +190,8 @@ public class RayCanvas extends Canvas {// implements Runnable {
if (getCell((int) posX, (int) (posY + dirY * moveSpeed)) == 0) { if (getCell((int) posX, (int) (posY + dirY * moveSpeed)) == 0) {
posY += dirY * moveSpeed; posY += dirY * moveSpeed;
} }
} }else
//move backwards if no wall behind you if (keyb.getKeyState(DOWN)) {//move backwards if no wall behind you
if (keyb.getKeyState(DOWN)) {
if (getCell((int) (posX - dirX * moveSpeed), (int) posY) == 0) { if (getCell((int) (posX - dirX * moveSpeed), (int) posY) == 0) {
posX -= dirX * moveSpeed; posX -= dirX * moveSpeed;
} }
@ -189,8 +199,14 @@ public class RayCanvas extends Canvas {// implements Runnable {
posY -= dirY * moveSpeed; posY -= dirY * moveSpeed;
} }
} }
boolean isRight = keyb.getKeyState(RIGHT);
boolean isLeft = keyb.getKeyState(LEFT);
if(glukmode[0]==3 && gluk==3) {
if(isRight) {isRight = false; isLeft = true;}
else if(isLeft) {isLeft = false; isRight = true;}
}
//rotate to the right //rotate to the right
if (keyb.getKeyState(RIGHT)) { if (isRight) {
//both camera direction and camera plane must be rotated //both camera direction and camera plane must be rotated
double oldDirX = dirX; double oldDirX = dirX;
dirX = dirX * Math.cos(-rotSpeed) - dirY * Math.sin(-rotSpeed); dirX = dirX * Math.cos(-rotSpeed) - dirY * Math.sin(-rotSpeed);
@ -198,9 +214,8 @@ public class RayCanvas extends Canvas {// implements Runnable {
double oldPlaneX = planeX; double oldPlaneX = planeX;
planeX = planeX * Math.cos(-rotSpeed) - planeY * Math.sin(-rotSpeed); planeX = planeX * Math.cos(-rotSpeed) - planeY * Math.sin(-rotSpeed);
planeY = oldPlaneX * Math.sin(-rotSpeed) + planeY * Math.cos(-rotSpeed); planeY = oldPlaneX * Math.sin(-rotSpeed) + planeY * Math.cos(-rotSpeed);
} }else
//rotate to the left if (isLeft) {//rotate to the left
if (keyb.getKeyState(LEFT)) {
//both camera direction and camera plane must be rotated //both camera direction and camera plane must be rotated
double oldDirX = dirX; double oldDirX = dirX;
dirX = dirX * Math.cos(rotSpeed) - dirY * Math.sin(rotSpeed); dirX = dirX * Math.cos(rotSpeed) - dirY * Math.sin(rotSpeed);
@ -210,6 +225,7 @@ public class RayCanvas extends Canvas {// implements Runnable {
planeY = oldPlaneX * Math.sin(rotSpeed) + planeY * Math.cos(rotSpeed); planeY = oldPlaneX * Math.sin(rotSpeed) + planeY * Math.cos(rotSpeed);
} }
g.drawImage(pr, w / 2, h / 2, 3);
if(showUI) showLabirinth(g, (int)posX, (int)posY); if(showUI) showLabirinth(g, (int)posX, (int)posY);
if (end) { if (end) {
g.setColor(0xFF6159); g.setColor(0xFF6159);
@ -246,6 +262,15 @@ public class RayCanvas extends Canvas {// implements Runnable {
end = false; end = false;
posX = 1; posX = 1;
posY = 1.1; posY = 1.1;
for(int i=0; i<glukmode.length; i++) {
glukstep[i] = 1;
glukmode[i] = (byte) grid.getRandomInt(4);
colors[1][i] = grid.getRandomInt(0xbbbbbb)+0x333333;
colors[2][i] = grid.getRandomInt(0xbbbbbb)+0x333333;
colors[3][i] = grid.getRandomInt(0xbbbbbb)+0x333333;
}
glukstep[glukmode[2]] = 2;
if(glukmode[0]==2) glukstep[glukmode[3]] = 3;
} }
private void uiSize(int num) { private void uiSize(int num) {
@ -253,4 +278,30 @@ public class RayCanvas extends Canvas {// implements Runnable {
if(size<2) size = 2; if(size<2) size = 2;
else if(size>10) size = 10; else if(size>10) size = 10;
} }
protected void pointerPressed(int x, int y) {
int w3 = w/3;
int h3 = h/3;
if(y<h3 && (x>w3 && x<(w-w3))) keyPressed(UP);
else if(y>(h-h3) && (x>w3 && x<(w-w3))) keyPressed(DOWN);
if(x<w3 && (y>h3 && y<(h-h3))) keyPressed(LEFT);
else if(x>(w-w3) && (y>h3 && y<(h-h3))) keyPressed(RIGHT);
if(x<w3 && y<h3) keyPressed(KEY_STAR);
else if(x>(w-w3) && y<h3) keyPressed(KEY_NUM0);
else if(x<w3 && y>(h-h3)) keyPressed(-6);
else if(x>(w-w3) && y>(h-h3)) keyPressed(-7);
else if( (x>w3 && x<(w-w3)) && (y>h3 && y<(h-h3)) ) keyPressed(FIRE);
}
protected void pointerReleased(int x, int y) {
int w3 = w/3;
int h3 = h/3;
if(y<h3 && (x>w3 && x<(w-w3))) keyReleased(UP);
else if(y>(h-h3) && (x>w3 && x<(w-w3))) keyReleased(DOWN);
if(x<w3 && (y>h3 && y<(h-h3))) keyReleased(LEFT);
else if(x>(w-w3) && (y>h3 && y<(h-h3))) keyReleased(RIGHT);
}
} }

25
src/about.ru Normal file
View File

@ -0,0 +1,25 @@
RayCanvas
Цель игры - пройти лабиринт. Цвета стен, лабиринт и эффекты генерируются случайно.
Управление в игре:
Левый софт - сгенерировать новый лабиринт
Правый софт - сгенерировать новый лабиринт с другим размером
* - Показать карту
1,3 (при показе карты) - изменить размер ячеек карты
0 - выйти в меню
Также есть поддержка TouchScreen.
Копирайты:
Алгоритм построения лабиринта - Carol Hamer,
RayCasting C++ - http://www.student.kuleuven.be/~m0216922/CG/raycasting.html
Понравилась игра? Поддержи автора.
Web-Money:
R812612235196
Z155872305615
U217957409638
aNNiMON (Melnik Software)
22.01.2011
http://annimon.com/

View File

@ -0,0 +1,50 @@
/*
* aNNiMON 2011
* For more info visit http://annimon.com/
*/
package com.emos.ui;
import javax.microedition.lcdui.Canvas;
/**
* Расширенный класс Canvas
* @author aNNiMON
*/
public abstract class ECanvas extends Canvas {
public final int //константы клавиш
KEY_LSK = -6, //левый софт
KEY_RSK = -7; //правый софт
public final byte
PRESSED = 0,
REPEATED = 1,
RELEASED = 2;
public int w,h;
public ECanvas() {
setFullScreenMode(true);
w = getWidth();
h = getHeight();
}
public void keyPressed(int key) {
keyEvent(key, PRESSED);
}
public void keyRepeated(int key) {
keyEvent(key, REPEATED);
}
public void keyReleased(int key) {
keyEvent(key, RELEASED);
}
/**
* Обработчик клавиатуры
* @param key - код клавиши
* @param state - состояние клавиши (нажата, отпущена, зажата)
*/
public abstract void keyEvent(int key, byte state);
}

View File

@ -0,0 +1,20 @@
/*
* aNNiMON 2011
* For more info visit http://annimon.com/
*/
package com.emos.ui;
import javax.microedition.lcdui.Font;
/**
*
* @author aNNiMON
*/
public class EConst {
public static final Font
titleFont = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_LARGE),
mainFont = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_MEDIUM);
}

167
src/com/emos/ui/ESkin.java Normal file
View File

@ -0,0 +1,167 @@
/*
* aNNiMON 2011
* For more info visit http://annimon.com/
*/
package com.emos.ui;
import javax.microedition.lcdui.Graphics;
/**
*
* @author aNNiMON
*/
public class ESkin {
public static int
wBack = 0xBF610151, //фон окна (каёмки)
wBack2 = 0xBF7D0169, //фон заливки фигур каёмки
wTitle = 0xFF84C1, //цвет заголовка окна
lBack = 0xE81E1E1E, //фон рабочей области
bg = 0; //фон
public ESkin(int skin) {
bg = 0;
lBack = 0xE81E1E1E;
wBack = 0xBF610151;
if(skin!=0) { //ставим яркость
wTitle = changeHSV(wBack, 0, 20);
wTitle = changeHSV(wBack, 1, -0.50f);
wTitle = changeHSV(wBack, 2, 0.60f);//(h+20, s-50, v+62 (100))
wBack2 = changeHSV(wBack, 2, -0.1f);
for(int i=0; i<=2; i++) {
float delta = getHSV(skin, i) - getHSV(wBack, i);
if(delta>-0.05 && delta<0.05) continue;
wTitle = changeHSV(wTitle, i, delta);
wBack2 = changeHSV(wBack2, i, delta);
}
wBack = skin;
}else{
wBack2 = 0xBF7D0169;
wTitle = 0xFF84C1;
}
}
private static int changeHSV(int color, int c, float value) {//0-h, 1-s, 2-v
float[] hsb = new float[3];
int qa = (color >> 24) & 0xff;
int qr = (color >> 16) & 0xff;
int qg = (color >> 8) & 0xff;
int qb = color & 0xff;
hsb = RGBtoHSV(qr, qg, qb, hsb);
hsb[c]+=value;
if(c==0) while(hsb[0]>360) hsb[0]-=360;
else {
if(hsb[c]>1.0) hsb[c]=hsb[c]-1.0f;
else if(hsb[c]<0) hsb[c]=-hsb[c];
}
return (qa << 24) | HSVtoRGB(hsb[0], hsb[1], hsb[2]);
}
private static int HSVtoRGB(float h, float s, float v) {
float qr = 0, qg = 0, qb = 0;
int r = 0, g = 0, b = 0;
if(s==0.0 && h==-1.0) return ((int)v << 16) | ((int)v << 8) | (int)v;
int Hi = (int) ((h / 60) % 6);
float f = (float) (h / 60 - (float)Math.floor(h/60));
float p = (float) ((float)v*(1.0f - (float)s));
float q = (float) ((float)v*(1.0f - (float)f*(float)s));
float t = (float) ((float)v*(1.0f - (s*(1.0-f))));
switch(Hi) {
case 0: qr = v; qg = t; qb = p; break;
case 1: qr = q; qg = v; qb = p; break;
case 2: qr = p; qg = v; qb = t; break;
case 3: qr = p; qg = q; qb = v; break;
case 4: qr = t; qg = p; qb = v; break;
case 5: qr = v; qg = p; qb = q; break;
}
r = (int) (255 * qr); g = (int) (255 * qg); b = (int) (255 * qb);
return (r << 16) | (g << 8) | b;
}
private static float[] RGBtoHSV(int qr, int qg, int qb, float[] hsv) {
float h = 0, s, v;
if (hsv == null) {
hsv = new float[3];
}
float r = (float) qr/255; float g = (float) qg/255; float b = (float) qb/255;
v = (r > g) ? r : g;
if (b > v) v = b;
float min = (r < g) ? r : g;
if (b < min) min = b;
// hue
if(v==min) h=0;
if(v==r && g>=b) h = 60 * ((g-b)/(v-min));
if(v==r && g<b) h = 60 * ((g-b)/(v-min))+360;
if(v==g) h = 60 * ((b-r)/(v-min))+120;
if(v==b) h = 60 * ((r-g)/(v-min))+240;
//saturation
if(v==0) s = 0;
else s=((v - min)/v);//1-(min/max);
if(s==0) h=-1;
hsv[0] = h;
hsv[1] = s;
hsv[2] = v;
return hsv;
}
private static float getHSV(int color, int c) {//0-h, 1-s, 2-v
float[] hsb = new float[3];
int qr = (color >> 16) & 0xff;
int qg = (color >> 8) & 0xff;
int qb = color & 0xff;
hsb = RGBtoHSV(qr, qg, qb, hsb);
return hsb[c];
}
public static void drawVGradient (Graphics gr, int rgb1, int rgb2, int xn, int yn, int wdh, int hgt) {
int r,g,b;
int r1, r2, g1, g2, b1, b2;
r1=acolor(rgb1, 'r'); r2=acolor(rgb2, 'r');
g1=acolor(rgb1, 'g'); g2=acolor(rgb2, 'g');
b1=acolor(rgb1, 'b'); b2=acolor(rgb2, 'b');
wdh+=xn;
hgt+=yn;
for (int i=yn; i<hgt; i++) {
r=r1 + (((i - hgt) + 1) * (r2 - r1)) / (hgt - yn - 1) + (r2 - r1);
g=g1 + (((i - hgt) + 1) * (g2 - g1)) / (hgt - yn - 1) + (g2 - g1);
b=b1 + (((i - hgt) + 1) * (b2 - b1)) / (hgt - yn - 1) + (b2 - b1);
gr.setColor (r,g,b);
gr.drawLine (xn,i,wdh-1,i);
}
}
public static void drawHGradient (Graphics gr, int rgb1, int rgb2, int xn, int yn, int wdh, int hgt) {
int r,g,b;
int r1, r2, g1, g2, b1, b2;
r1=acolor(rgb1, 'r'); r2=acolor(rgb2, 'r');
g1=acolor(rgb1, 'g'); g2=acolor(rgb2, 'g');
b1=acolor(rgb1, 'b'); b2=acolor(rgb2, 'b');
wdh+=xn;
hgt+=yn;
for (int i=xn; i<wdh; i++) {
r=r1+(((i-wdh)+1)*(r2-r1))/(wdh-xn-1)+(r2-r1);
g=g1+(((i-wdh)+1)*(g2-g1))/(wdh-xn-1)+(g2-g1);
b=b1+(((i-wdh)+1)*(b2-b1))/(wdh-xn-1)+(b2-b1);
if(r>255) r=255;
else if(r<0) r=0;
if(g>255) g=255;
else if(g<0) g=0;
if(b>255) b=255;
else if(b<0) b=0;
gr.setColor (r,g,b);
gr.drawLine (i,yn,i,hgt-1);
}
}
private static int acolor(int argb, char c) {
int bitmask = 0;
if(c=='b') return (argb & 0xff);
else if(c=='a') bitmask = 24;
else if(c=='r') bitmask = 16;
else if(c=='g') bitmask = 8;
return ((argb >> bitmask) & 0xff);
}
}

View File

@ -0,0 +1,64 @@
/*
* aNNiMON 2011
* For more info visit http://annimon.com/
*/
package com.emos.ui;
import javax.microedition.lcdui.Graphics;
/**
* Класс окна EmOS
* @author aNNiMON
*/
public abstract class EWindow extends ECanvas {
private String title;
private int fh,fw;
private final int otst = 5;
protected int ww,hh; //размеры рабочей области
public EWindow(String title) {
super();
this.title = title;
fw = EConst.titleFont.stringWidth(title)+title.length();
fh = EConst.titleFont.getHeight();
ww = w-otst*2;
hh = h-fh-otst*2;
}
public void paint(Graphics g) {
//Рисуем задний фон
g.setColor(ESkin.bg);
g.fillRect(0, 0, w, h);
//Рисуем фон окна (каёмки)
g.setColor(ESkin.wBack);
g.fillRoundRect(0, otst, w, h-otst, 5, 5);
g.setColor(ESkin.wBack2);
g.fillRoundRect(w/2-fw/2, 0, fw, fh, 5, 5);
//Рисуем текст заголовка
g.setFont(EConst.titleFont);
g.setColor(ESkin.wTitle);
g.drawString(title, w/2, 0, 17);
//Рисуем фон рабочей области
g.setClip(otst, fh+otst, ww, hh);
g.setColor(ESkin.lBack);
g.translate(otst, fh+otst);
g.fillRect(0, 0, ww, hh);
paint(g, ww, hh);
}
//Перерисовка рабочей области окна
protected void redraw() {
repaint(otst, fh+otst, ww, hh);
}
/**
* Метод отрисовки рабочей области окна
* @param g - Graphics
* @param w - ширина рабочей области
* @param h - высота рабочей области
*/
public abstract void paint(Graphics g, int w, int h);
}

View File

@ -0,0 +1,58 @@
package com.emos.ui;
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;
}
public static byte encodeCharCP1251 (char ch)
{
if (ch > 0 && ch < 128)
return (byte) ch;
else if (ch == 0x401)
return -88; // ¨
else if (ch == 0x404)
return -86; // ª
else if (ch == 0x407)
return -81; // ¯
else if (ch == 0x451)
return -72; // ¸
else if (ch == 0x454)
return -70; // º
else if (ch == 0x457)
return -65; // ¿
return (byte)((byte)(ch) + 176);
}
public static char checkCP1251 (char ch)
{
int bt = (byte) ch;
if(bt < 0) return decodeCharCP1251((byte) (256 + bt));
else return ch;
}
}