here is my code for the snake game, the thing i need to do is generate location for the snake food, once the snake touch the snake food, it will regenerate the location of the food~pls, i really need your guys help!!! just kindly have a look
package snake;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
public class SnakeCanvas extends Canvas{
private int currentX =getWidth()/2;
private int currentY =getHeight()/2;
private boolean condition = false;
private boolean position = false;
Random rand = new Random();
int randomX=rand.nextInt(180) + 20;
int randomY =rand.nextInt(250) + 20;
private final Midlet midlet;
private int score = 0;
Timer t;
public SnakeCanvas(Midlet midlet)
{
this.midlet = midlet;
t = new Timer();
t.schedule(new TimerTask() {
public void run() {
if((condition==false)&&(position==false))
{
currentY -= 5 ;
}
if((condition==false)&&(position==true))
{
currentY += 5 ;
}
if((condition==true)&&(position==false))
{
currentX -= 5 ;
}
if((condition==true)&&(position==true))
{
currentX += 5 ;
}
}
}, 50, 50);
}
public void paint(Graphics g) {
boolean touch=false;
//drawing Background
g.setColor(0x000000);
g.fillRect(0, 0, getWidth(), getHeight());
//drawing snake
g.setColor(0xffffff);
g.fillRoundRect(currentX, currentY, 20, 20, 5, 5);
//snake food
g.setColor(234,41,42);
g.fillRect(randomX,randomY,10,10);
if((currentX-9<=randomX+4&¤tX+9>=randomX-4)&&(currentY-9<=randomY+4&¤tY+9>=randomY-4)){
addScore();
}
//drawing block
g.setColor(82,133,190);
g.fillRect(0, 0, getWidth(), 5);
g.fillRect(0, getHeight()-5, getWidth(), 5);
g.fillRect(0, 0, 5, getHeight());
g.fillRect(getWidth()-5, 0, 5, getHeight());
if((currentX>=getWidth()-10)||(currentX<5)||(currentY>=getHeight()-5)||(currentY<5))
midlet.GameOver();
g.setColor(142,255,17);
g.drawString("Score : "+score, 8, 7, Graphics.TOP|Graphics.LEFT);
repaint();
}
protected void keyPressed(int keyCode) {
System.out.println(keyCode);
switch(keyCode)
{
case -1:
condition = false;
position = false;
break;
case -2:
condition = false;
position = true;
break;
case -3:
condition = true;
position = false;
break;
case -4:
condition = true;
position= true;
break;
}
repaint();
}
private void addScore() {
score=score+1;**strong text**
}
private void food(){
Random rand = new Random();
int randomX=rand.nextInt(150) + 20;
int randomY=rand.nextInt(250) + 20;
}
}
Okay. I don't know if you managed to solve your problem but there seems to be a couple things wrong with your code.
First in this code block in the beginning:
Private int currentX =getWidth()/2;
private int currentY =getHeight()/2;
private boolean condition = false;
private boolean position = false;
Random rand = new Random();
int randomX=rand.nextInt(180) + 20;
int randomY =rand.nextInt(250) + 20;
^I am sure this does not compile, you can't have function calls when declaring header variables.
Second
if((condition==false)&&(position==false))
{
currentY -= 5 ;
}
if((condition==false)&&(position==true))
{
currentY += 5 ;
}
if((condition==true)&&(position==false))
{
currentX -= 5 ;
}
if((condition==true)&&(position==true))
{
currentX += 5 ;
}
}
}, 50, 50);
}
Your block coding style is horrible and hard to read. http://en.wikipedia.org/wiki/Programming_style#Indentation has a good guide on mastering this, read it!
This applies to your switch/case statements too!
Lastly your question:
private void food(){
Random rand = new Random();
int randomX=rand.nextInt(150) + 20;
int randomY=rand.nextInt(250) + 20;
}
^ Just generates random numbers, but doesn't do anything with them. I am guessing you meant:
private void food(){
Random rand = new Random();
randomX=rand.nextInt(150) + 20;
randomY=rand.nextInt(250) + 20;
}
which sets the classes global randomX and randomY to new values.
This doesn't help though since you don't actually call the Food() function anywhere in this class! And considering it is "Private" and can only be used by this class that must be an error.
tl;dr You need to study programming some more, but it is a good effort. I will help you more in the comments if you like. If my answer helped, please accept it.
Fenix
Related
I made a test game in unity that makes it so when I click on a button, it spawns a cylinder created from a factory class. I'm trying to make it so when I create the cylinder, its height shrinks over the next 20 seconds. Some methods I found are difficult to translate into what I'm doing. If you could lead me to the right direction, I'd very much appreciate it.
Here's my code for the cylinder class
public class Cylinder : Shape
{
public Cylinder()
{
GameObject cylinder = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
cylinder.transform.position = new Vector3(3, 0, 0);
cylinder.transform.localScale = new Vector3(1.0f, Random.Range(1, 2)-1*Time.deltaTime, 1.0f);
cylinder.GetComponent<MeshRenderer>().material.color = Random.ColorHSV();
Destroy(cylinder, 30.0f);
}
}
This can be done with the Time.deltaTime and Vector3.Lerp in a coroutine function. Similar to Rotate GameObject over time and Move GameObject over time questions. Modified it a little bit to do just this.
bool isScaling = false;
IEnumerator scaleOverTime(Transform objectToScale, Vector3 toScale, float duration)
{
//Make sure there is only one instance of this function running
if (isScaling)
{
yield break; ///exit if this is still running
}
isScaling = true;
float counter = 0;
//Get the current scale of the object to be moved
Vector3 startScaleSize = objectToScale.localScale;
while (counter < duration)
{
counter += Time.deltaTime;
objectToScale.localScale = Vector3.Lerp(startScaleSize, toScale, counter / duration);
yield return null;
}
isScaling = false;
}
USAGE:
Will scale GameObject within 20 seconds:
StartCoroutine(scaleOverTime(cylinder.transform, new Vector3(0, 0, 90), 20f));
Check out Lerp. A general example of how to use it would be something like this:
float t = 0;
Update()
{
t += Time.deltaTime;
cylinder.localScale = new Vector3(1, Mathf.Lerp(2f, 1f, t/3f), 1); // shrink from 2 to 1 over 3 seconds;
}
You will create a new monobehaviour script and add it to your primitive. Then you wil use "Update" method of monobehaviour (or use coroutine) for change object over time.
Monobehaviour must be look like this:
public class ShrinkBehaviour : MonoBehaviour
{
bool isNeedToShrink;
Config currentConfig;
float startTime;
float totalDistance;
public void StartShrink(Config config)
{
startTime = Time.time;
currentConfig = config;
totalDistance = Vector3.Distance(currentConfig.startSize, currentConfig.destinationSize);
isNeedToShrink = true;
transform.localScale = config.startSize;
}
private void Update()
{
if (isNeedToShrink)
{
var nextSize = GetNextSize(currentConfig);
if (Vector3.Distance(nextSize, currentConfig.destinationSize) <= 0.05f)
{
isNeedToShrink = false;
return;
}
transform.localScale = nextSize;
}
}
Vector3 GetNextSize(Config config)
{
float timeCovered = (Time.time - startTime) / config.duration;
var result = Vector3.Lerp(config.startSize, config.destinationSize, timeCovered);
return result;
}
public struct Config
{
public float duration;
public Vector3 startSize;
public Vector3 destinationSize;
}
}
For using this, you must do next:
public Cylinder()
{
GameObject cylinder = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
var shrink = cylinder.AddComponent<ShrinkBehaviour>();
shrink.StartShrink(new ShrinkBehaviour.Config() { startSize = Vector3.one * 10, destinationSize = Vector3.one * 1, duration = 20f });
cylinder.transform.position = new Vector3(3, 0, 0);
cylinder.GetComponent<MeshRenderer>().material.color = Random.ColorHSV();
Destroy(cylinder, 30.0f);
}
You must remember, monobehaviour-script must be in separate file, and must have name similar to monobehaviour-class name. For example, ShrinkBehaviour.cs;
Hello I am developing a game on my spare time with AIDE and libGDX. Though AIDE has some missing methods of the libGDX API and I had to create some workarounds to compensate for the missing methods.
So my problem is that with every instance of a collision the app becomes more and more laggy. No new textures are being drawn and non go away. Just a poor implementation that is meant to push you out of said collision tile. It runs fine until you have a few collisions. My thought is that it creates a new variable with every collision and stores it into memory causing a leak. But I can't really tell if that is the case. Oh I'd like to add that I don't have access to a computer, just my phone. Here is my movement class
move.java
public class move
{
float posX;
float posY;
float touchedOnScreenX;
float touchedOnScreenY;
float centerOfScreenX;
float centerOfScreenY;
float posXSetter;
float posYSetter;
float Speed = 150;
float mapBoundsWidth;
float mapBoundsHeight;
boolean upperBounds;
boolean lowerBounds;
boolean rightBounds;
boolean leftBounds;
boolean tileCollition;
public move() {
}
public void renderMove(float delta) {
if(Gdx.input.isTouched()) {
screenAndTouchInfo();
checkBoundsBoolean();
checkForCollision();
}
}
//slows game down
private void checkForCollision()
{
if (upperBounds == false)
{
if (lowerBounds == false)
{
if (rightBounds == false)
{
if (leftBounds == false)
{
if (tileCollition == false)
{
movement();
}
else
{
collitionSide();
}
}
else
{
posX++;
}
}
else
{
posX--;
}
}
else
{
posY++;
}
}
else
{
posY --;
}
}
private void movement()
{
posYSetter = posY;
posXSetter = posX;
if (touchedOnScreenX < centerOfScreenX)
{
posX -= Gdx.graphics.getDeltaTime() * Speed;
}
else
{
posX += Gdx.graphics.getDeltaTime() * Speed;
}
if (touchedOnScreenY < centerOfScreenY)
{
posY -= Gdx.graphics.getDeltaTime() * Speed;
}
else
{
posY += Gdx.graphics.getDeltaTime() * Speed;
}
if (touchedOnScreenY < centerOfScreenY + 64 && touchedOnScreenY > centerOfScreenY - 64)
{
posY = posYSetter;
}
if (touchedOnScreenX < centerOfScreenX + 64 && touchedOnScreenX > centerOfScreenX - 64)
{
posX = posXSetter;
}
}
//buggy and slows game down. Can push you into tile if input is the opposite of the side
public void collitionSide() {
if (tileCollition == true){
if (touchedOnScreenX < centerOfScreenX)
{
posX = posX +10;
}
else
{
posX = posX - 10;
}
if (touchedOnScreenY < centerOfScreenY)
{
posY = posY +10;
}
else
{
posY = posY -10;
}
}
}
private void screenAndTouchInfo()
{
touchedOnScreenX = Gdx.input.getX();
touchedOnScreenY = (Gdx.graphics.getHeight() - Gdx.input.getY());
centerOfScreenX = Gdx.graphics.getWidth() / 2;
centerOfScreenY = Gdx.graphics.getHeight() / 2;
}
//slows game down
private void checkBoundsBoolean()
{
if (posX > mapBoundsWidth)
{
rightBounds = true;
}
else {
rightBounds = false;
}
if (posY > mapBoundsHeight)
{
upperBounds = true;
}
else {
upperBounds = false;
}
if (posX < mapBoundsWidth - mapBoundsWidth)
{
leftBounds = true;
}
else {
leftBounds = false;
}
if (posY < mapBoundsHeight - mapBoundsHeight)
{
lowerBounds = true;
}
else {
lowerBounds = false;
}
}
public void setTileCollision(boolean tileCollision) {
this.tileCollition = tileCollision;
}
public float getPosX() {
return posX;
}
public float getPosY() {
return posY;
}
public float getTouchedOnScreenX() {
return touchedOnScreenX;
}
public float getTouchedOnScreenY() {
return touchedOnScreenY;
}
public float getCenterOfScreenX() {
return centerOfScreenX;
}
public float getCenterOfScreenY() {
return centerOfScreenY;
}
public void setMapboundsWidth(float width) {
this.mapBoundsWidth = width;
}
public void setMapboundsHeight(float height) {
this.mapBoundsHeight = height;
}
}
I know that is a lot of code to comb through and I am sorry if it isn't always clear what is going on. I refactored it to where it would be a little easier to understand. Oh if anyone could tell me why AIDE is missing some methods of libGDX that would be nice too.The most notable one would be Cell.setTile(). That I know is in libGDX's API and can be found in their documentation. But when I implement it it throws a unknown method of class Cell error. I have researched on how to use the method as well with no avail. Had to create int[][] map and a for loop to draw map with another Texture[]. It works. Lol. Thank you to whomever even took the time to look at my long winded double question. Hopefully someone can tell me why this lag is created from said collisions.
I recommend moving your collision code into a separate thread. This should improve performance significantly:
Executor executor = Executors.newSingleThreadExecutor();
executor.execute(new Runnable() {
#Override
public void run() {
// Physics loop goes here
}
});
Make sure to shutdown the executor when disposing your screen.
I wanna write a Snake game with javaFX , but there is exception that I don't know about and I want to know how to fix it. ( i know it's not complete yet )
and I want to know , the class that extends Application ( with start override )
is exactly the main in other programs?
as you see , here is not static void main BC I didn't need, but if i want to add main where shoud i do?
it's the Exeption...
Exception in Application constructor
Exception in thread "main" java.lang.NoSuchMethodException: Main_Snake.main([Ljava.lang.String;)
at java.lang.Class.getMethod(Class.java:1819)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:125)
and my code is :
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import java.util.ArrayList;
/**
* Created by Nadia on 1/5/2016.
*/
public class Main_Snake extends Application{
Snake snake = new Snake();
Apple apple = new Apple();
Canvas canvas = new Canvas(800, 600);
boolean goNorth = true, goSouth, goWest, goEast;
int x, y = 0; // marbut be apple
boolean j = false;
// int gm_ov = 0; // vase game over shodan
ArrayList<Integer> X = new ArrayList<Integer>();
ArrayList<Integer> Y = new ArrayList<>();
#Override
public void start(Stage primaryStage) throws Exception {
BorderPane b = new BorderPane(canvas);
Scene scene = new Scene(b, 800, 600);
primaryStage.setScene(scene);
primaryStage.show();
//KeyBoard(scene);
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent e) {
switch (e.getText()) {
case "w":
if (!goSouth) {
goNorth = true;
goSouth = false;
goWest = false;
goEast = false;
}
break;
case "s":
if (!goNorth) {
goSouth = true;
goNorth = false;
goWest = false;
goEast = false;
}
break;
case "a":
if (!goEast) {
goWest = true;
goEast = false;
goSouth = false;
goNorth = false;
}
break;
case "d":
if (!goWest) {
goEast = true;
goWest = false;
goSouth = false;
goNorth = false;
}
break;
}
}
});
play();
}
public void play(){
AnimationTimer timer = new AnimationTimer() {
private long lastUpdate = 0;
#Override
public void handle(long now) {
if (now - lastUpdate >= 40_000_000) { // payin avordane sor#
snake.pos_S(); // har bar mar rasm mishe bad az move va ye sib ba X,Y khodesh rasm mishe tu tabe move dar morede tabe Point hast
apple.pos_A();
apple.random_Pos();
snake.Move();
lastUpdate = now; // sor#
}
}
};
timer.start();
}
/* public void KeyBoard(Scene scene) {
}*/
}
class Apple extends Main_Snake {
public void random_Pos() {
if (j == false) { // ye sib bede ke ru mar nabashe ( rasmesh tu rasme )
do {
x = (int) (Math.random() * 790 + 1);
y = (int) (Math.random() * 590 + 1);
} while (X.indexOf(x) != -1 && Y.get(X.indexOf(x)) == y || x % 10 != 0 || y % 10 != 0);
/*inja aval chek kardam tu araylist x hast ya na ag bud sharte aval ok hala sharte do ke tu Y ham mibinim tu hamun shomare khune
y barabare y mast ag bud pas ina bar ham montabeghan va sharte dovom ham ok . 2 sharte akhar ham vase ine ke mare ma faghat mazrab
haye 10 and pas ta vaghti in se shart bargharare jahayie ke ma nemikhaym va hey jaye dg mide*/
j = true;
}
}
public void pos_A() {
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.setFill(Color.BLACK);
gc.fillRect(x, y, 10, 10);
}
public void Point() {
if (X.get(0) == x && Y.get(0) == y) {
j = false;
}
}
}
class Snake extends Main_Snake {
Snake(){ //cunstructor
X.add(400);
Y.add(300);
X.add(400);
Y.add(310);
X.add(400);
Y.add(320);
X.add(400);
Y.add(330);
X.add(400);
Y.add(340);
}
public void pos_S(){
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.setFill(Color.WHITE);
gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
apple.pos_A();
// keshidane mar (body yeki ezafe tar az adade morabaA mide)
for (int i = X.size() - 1; i >= 0; i--)
gc.fillRect(X.get(i), Y.get(i), 10, 10);
}
public void Move(){
int Px = X.get(X.size() - 1);
int Py = Y.get(Y.size() - 1);
for (int z = X.size() - 1 ; z > 0 ; z--){
X.remove(z);
X.add(z , X.get(z-1) ) ;
Y.remove(z);
Y.add(z , Y.get(z-1) ) ;
}
if (goNorth) {
Y.add(0 , Y.get(0) - 10);
Y.remove(1);
}
if (goSouth) {
Y.add(0 , Y.get(0) + 10);
Y.remove(1);
}
if (goEast) {
X.add(0 , X.get(0) + 10);
X.remove(1);
}
if (goWest) {
X.add(0 , X.get(0) - 10);
X.remove(1);
}
apple.Point(); // emtiaz gerefte
if ( j == false) {
X.add(Px);
Y.add(Py);
}
if ( X.get(0) > 790 ){
X.remove(0);
X.add(0 , 0);
}
if ( X.get(0) < 0 ){
X.remove(0);
X.add(0 , 800);
}
if ( Y.get(0) > 590 ){
Y.remove(0);
Y.add(0 , 0);
}
if ( Y.get(0) < 0 ){
Y.remove(0);
Y.add(0 , 600);
}
}
}
The standard Oracle Java Runtime Environment can execute Application subclasses directly from the command line, even if they do not contain a main method. So assuming you are using a standard JRE, from the command line you can execute
java Main_Snake
and it will run (assuming no other errors, etc).
Other environments, and most IDEs, don't support this execution mode, so if you want to run in those environments (including running in Eclipse, for example), you need a main(...) method which launches your JavaFX application. So just add
public static void main(String[] args) {
launch(args);
}
to the Main_Snake class.
I've been following this tutorial here: Link to tutorial. I can't seem to get the application displaying properly though. When I run the application I expect to see a screen like CalendarCanvas from tutorial, but I get this:
Here is my code, I'm using standard MIDP classes.
Class CreateCalendar:
import java.util.Date;
import java.util.Calendar;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
public class CreateCalendar
{
/**
* Array of strings which holds data for the month and day
* for the calendar application.
*/
static final String[] month_labels = new String[]
{
"January", "Febuary", "March", "April", "May", "June", "July", "August", "Sepetember", "October", "November", "Decemeber"
};
static final String[] weekdays_labels = new String[]
{
"Mon", "Tue", "Wed", "Thur", "Fri", "Sat", "Sun"
};
public int startWeekday = 0;
public int padding = 1;
public int borderWidth = 4;
public int borderColor = 0x009900;
/**
* Weekday Labels
*/
public Font weekdayFont = Font.getDefaultFont();
public int weekdayBackgroundColor = 0x009900;
public int weekdayColor = 0xffffff;
/**
* Month/Year Labels
*/
public Font headerFont = Font.getDefaultFont();
public int headerBackgroundColor = 0x009900;
public int headerColor = 0xffffff;
/**
* Cells Labels
*/
public Font font = Font.getDefaultFont();
public int foreColor = 0xffffff;
public int backgroundColor = 0x009900;
public int selectedBackgroundColor = 0xCCFF00;
public int selectedForegroundColor = 0xffffff;
/**
* Size properties
*/
int width = 0;
int height = 0;
int headerHeight = 0;
int weekHeight = 0;
int cellWidth = 0;
int cellHeight = 0;
/**
* Internal time properties
*/
long currentTimeStamp = 0;
Calendar calendar = null;
int weeks = 0;
public CreateCalendar(Date date)
{
calendar = Calendar.getInstance();
setDate(date);
initialize();
}
public Date getSelectedDate()
{
return calendar.getTime();
}
public void setDate(Date d)
{
currentTimeStamp = d.getTime();
calendar.setTime(d);
this.weeks = (int)Math.ceil(((double)getStartWeekday() + getMonthDays()) / 7);
}
public void setDate(long timestamp)
{
setDate(new Date(timestamp));
}
public void initialize()
{
this.cellWidth = font.stringWidth("MM") + 2 * padding;
this.cellHeight = font.getHeight() + 2 * padding;
this.headerHeight = headerFont.getHeight() + 2 * padding;
this.weekHeight = weekdayFont.getHeight() + 2 * padding;
this.width = 7 * (cellWidth + borderWidth) + borderWidth;
initHeight();
}
void initHeight()
{
this.height = headerHeight + weekHeight + this.weeks * (cellHeight + borderWidth) + borderWidth;
}
int getMonthDays()
{
int month = calendar.get(Calendar.MONTH);
switch (month)
{
case 3:
case 5:
case 8:
case 10:
return 30;
case 1:
int year = calendar.get(Calendar.YEAR);
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) ? 29 : 28;
default:
return 31;
}
}
int getStartWeekday()
{
Calendar c = Calendar.getInstance();
c.set(Calendar.MONTH, calendar.get(Calendar.MONTH));
c.set(Calendar.YEAR, calendar.get(Calendar.YEAR));
c.set(Calendar.DAY_OF_MONTH, 1);
return (c.get(Calendar.DAY_OF_WEEK) + 5) % 7;
}
public void KeyPressed(int key)
{
switch(key)
{
case Canvas.UP:
go(-7);
break;
case Canvas.DOWN:
go(7);
break;
case Canvas.RIGHT:
go(1);
break;
case Canvas.LEFT:
go(-1);
break;
}
}
void go(int delta)
{
int prevMonth = calendar.get(Calendar.MONTH);
setDate(currentTimeStamp + 864000000 * delta);
if(calendar.get(Calendar.MONTH) != prevMonth)
{
initHeight();
}
}
public void paint(Graphics g)
{
g.setColor(backgroundColor);
g.fillRect(0, 0, width, height);
g.setFont(headerFont);
g.setColor(headerColor);
g.drawString(month_labels[calendar.get(Calendar.MONTH)] + " " + calendar.get(Calendar.YEAR), width / 2, padding, Graphics.TOP | Graphics.HCENTER);
g.translate(0, headerHeight);
g.setColor(weekdayBackgroundColor);
g.fillRect(0, 0, width, weekHeight);
g.setColor(weekdayColor);
g.setFont(weekdayFont);
for(int i = 0; i < 7; i++)
{
g.drawString(weekdays_labels[(i + startWeekday) % 7], borderWidth + i * (cellWidth + borderWidth) + cellWidth / 2, padding, Graphics.TOP | Graphics.HCENTER);
}
g.translate(0, weekHeight);
g.setColor(borderColor);
for(int i = 0; i <= weeks; i++)
{
g.fillRect(0, i * (cellHeight + borderWidth), width, borderWidth);
}
for(int i = 0; i <=7; i++)
{
g.fillRect(i * (cellWidth + borderWidth), 0, borderWidth, height - headerHeight - weekHeight);
}
int days = getMonthDays();
int dayIndex = (getStartWeekday() - this.startWeekday + 7) % 7;
g.setColor(foreColor);
int currentDay = calendar.get(Calendar.DAY_OF_MONTH);
for(int i = 0; i < days; i++)
{
int weekday = (dayIndex + i) % 7;
int row = (dayIndex + i) / 7;
int x = borderWidth + weekday * (cellWidth + borderWidth) + cellWidth / 2;
int y = borderWidth + row * (cellHeight + cellWidth) + padding;
if(i + 1 == currentDay)
{
g.setColor(selectedBackgroundColor);
g.fillRect(borderWidth + weekday * (cellWidth + borderWidth), borderWidth + row * (cellHeight + borderWidth), cellWidth, cellHeight);
g.setColor(selectedForegroundColor);
}
g.drawString("" + (i + 1), x, y, Graphics.TOP | Graphics.HCENTER);
if(i + 1 == currentDay)
{
g.setColor(foreColor);
}
}
g.translate(0, - headerHeight - weekHeight);
}
private Date getTime() {
throw new UnsupportedOperationException("Not yet implemented"); //TODO get current Time
}
Class CalFrontEnd (extends MIDlet):
public class CalFrontEnd extends MIDlet
{
public CreateCalendar calendar;
protected Display display;
protected Form mainForm;
public CalFrontEnd()
{
}
public void startApp()
{
calendar = new CreateCalendar(new Date());
calendar.headerFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_LARGE);
calendar.weekdayFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_MEDIUM);
calendar.weekdayBackgroundColor = 0xccccff;
calendar.weekdayColor = 0x0000ff;
calendar.headerColor = 0xffffff;
calendar.initialize();
display.getDisplay(this).setCurrent(
new intCalendar(this));
}
public void pauseApp()
{
}
public void destroyApp(boolean destroy)
{
notifyDestroyed();
}
}}
Code in the class CreateCalendar looks very problematic.
In prior question you mentioned few minor variable name differences done to code from tutorial, but from what is shown in your code snippet, this is not so.
To find a way to reuse tutorial code, most straightforward approach would be like as follows.
Copy the source code from tutorial - files CalendarWidget.java and CalendarCanvas.java
Copy as-is, only adjust the package statements if necessary.
Modify CalFrontEnd about as follows
if needed, add import statement for CalendarCanvas
replace current code in startApp with simplest invocation for CalendarCanvas, like this:
public void startApp() {
Display.getDisplay(this).setCurrent(
new CalendarCanvas(this));
}
Test the code, tune and fix it until your MIDlet shows what you would expect of CalendarCanvas
After above is done, proceed with modifying the code to further match your needs.
Don't forget to test the changes you make, to make sure that things indeed work as you expect.
Is there any way to create a Tab Menu in j2me?
I found a code but I am unable to understand it
In this code there is Tab Menu created which is in Canvas class and then Tab menu is created which is totally done in Canvas or painted. The only part I found difficult to grasp was the void go() method and then
When I try to draw anything above and below this code using paint method, it doesn't work - what's the problem?
Below is the code
// Tab Menu CANVAS class
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
public class TabMenuCanvas extends Canvas
{
TabMenu menu = null;
public TabMenuCanvas()
{
menu = new TabMenu(
new String[]{"Home", "News", "Community", "Your files", "Credits", "Events", "Blog", "Upload", "Forum Nokia"},
getWidth() - 20
);
}
protected void keyPressed(int key)
{
int gameAction = getGameAction(key);
if(gameAction == Canvas.RIGHT)
{
menu.goRight();
repaint();
}
else if(gameAction == Canvas.LEFT)
{
menu.goLeft();
repaint();
}
}
protected void paint(Graphics g)
{
g.translate(10, 30);
menu.paint(g);
g.translate(- 10, - 30);
}
}
// Tab Menu Class
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
public class TabMenu
{
int background = 0xffffff;
int bgColor = 0xcccccc;
int bgFocusedColor = 0x0000ff;
int foreColor = 0x000000;
int foreFocusedColor = 0xffffff;
int cornerRadius = 6;
int padding = 2;
int margin = 2;
Font font = Font.getDefaultFont();
int scrollStep = 20;
int selectedTab = 0; //selected tab index
int[] tabsWidth = null; //width of single tabs
int[] tabsLeft = null; //left X coordinate of single tabs
int tabHeight = 0; //height of tabs (equal for all tabs)
String[] tabs = null; //tab labels
int menuWidth = 0; //total menu width
int viewportWidth = 0; //visible viewport width
int viewportX = 0; //current viewport X coordinate
public TabMenu(String[] tabs, int width)
{
this.tabs = tabs;
this.viewportWidth = width;
initialize();
}
void initialize()
{
tabHeight = font.getHeight() + cornerRadius + 2 * padding; //[ same for all tabs]
menuWidth = 0;
tabsWidth = new int[tabs.length];
tabsLeft = new int[tabs.length];
for(int i = 0; i < tabsWidth.length; i++)
{
tabsWidth[i] = font.stringWidth(tabs[i]) + 2 * padding + 2 * cornerRadius;
tabsLeft[i] = menuWidth;
menuWidth += tabsWidth[i];
if(i > 0)
{
menuWidth += margin;
}
}
}
public void goRight()
{
go(+1);
}
public void goLeft()
{
go(-1);
}
private void go(int delta)
{
int newTab = Math.max(0, Math.min(tabs.length - 1, selectedTab + delta));
boolean scroll = true;
if(newTab != selectedTab && isTabVisible(newTab))
{
selectedTab = newTab;
if( (delta > 0 && tabsLeft[selectedTab] + tabsWidth[selectedTab] > viewportX + viewportWidth) ||
(delta < 0 && tabsLeft[selectedTab] < viewportX))
{
scroll = true;
}
else
{
scroll = false;
}
}
if(scroll)
{
viewportX = Math.max(0, Math.min(menuWidth - viewportWidth, viewportX + delta * scrollStep));
}
}
private boolean isTabVisible(int tabIndex)
{
return tabsLeft[tabIndex] < viewportX + viewportWidth &&
tabsLeft[tabIndex] + tabsWidth[tabIndex] >= viewportX;
}
public void paint(Graphics g)
{
int currentX = - viewportX;
g.setClip(0, 0, viewportWidth, tabHeight);
g.setColor(background);
g.fillRect(0, 0, viewportWidth, tabHeight);
for(int i = 0; i < tabs.length; i++)
{
g.setColor(i == selectedTab ? bgFocusedColor : bgColor);
g.fillRoundRect(currentX, 0, tabsWidth[i], tabHeight + cornerRadius, 2 * cornerRadius, 2 * cornerRadius);
g.setColor(i == selectedTab ? foreFocusedColor : foreColor);
g.drawString(tabs[i], currentX + cornerRadius + padding, cornerRadius + padding, Graphics.LEFT | Graphics.TOP);
currentX += tabsWidth[i] + margin;
}
}
}
When I try to draw anything above and below this code using paint method, it doesn't work
what of the paint methods you use to draw above and below? Pay attention that there are two methods named that way - first is in TabMenuCanvas, second is in TabMenu (second method is invoked from TabMenuCanvas#repaint).
whatever you would try to draw in TabMenuCanvas#paint will most likely be overwritten by setClip and fillRect when TabMenu#paint is invoked following repaint request
The only place where one can expect to be able to draw something visible seems to be in TabMenu#paint method, inside the clip area that is set there.
You can use GUI Libraries for J2ME,for example Lightweight User Interface Toolkit (LWUIT),Flemil have "tab menu".You can see list of GUI Libraries here.