Android Game Java removing a Bitmap from a linked list - java

So, I have a various Bitmaps on my canvas that are animated as individual classes.
When the Bitmap goes off screen i want the Bitmap to be removed from the linkedlist. they are in a linkedlist as there can be more than one of the same bitmap on the screen.
The bitmap is removing from the screen but it is still in the linkedlist as the linkedlist size is 1.
If i add more than one bitmap to the linkedlist they both get drawn but when on goes of the screen the game crashes.
Panel Class.
public void doDraw(long elapsed, long score, Canvas canvas) {
canvas.drawBitmap(background, 0, 0, null); // draw a black background
synchronized (mChimneys) {
if ((mPresents.size() < 3)) {
for (Present presents : mPresents) {
presents.doDraw(canvas);
}
}
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
synchronized (mChimneys) {
float x = event.getX();
float y = event.getY();
float mX = 0;
float mY = 0;
int mWidth = 0;
int mHeight = 0;
for (Santa santas : mSantas) {
mX = santas.getmX();
mY = santas.getmY();
mWidth = santas.getmBitmap().getWidth();
mHeight = santas.getmBitmap().getHeight();
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (x >= mX && x < (mX + mWidth) && y >= mY
&& y < (mY + mHeight)) {
if ((mPresents.size() < 4)) {
mPresents.add(new Present(getResources(), mX, mY));
mPresentNumber = mPresents.size();
}
}
}
}
return true;
}
public void animate(long elapsedTime) {
synchronized (mChimneys) {
for (Present presents : mPresents) {
boolean remove = presents.animate(elapsedTime);
if (remove) {
mPresents.remove(presents);
}
}
}
Present Class.
package com.droidnova.android;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
public class Present {
private float mX;
private float mY;
private Bitmap mBitmap;
private int mSpeedY;
Panel panel;
public Present(Resources res, float x, float y) {
Random rand = new Random();
List<Integer> my_presents = new LinkedList<Integer>();
my_presents.add(R.drawable.presentblue);
my_presents.add(R.drawable.presentpurple);
my_presents.add(R.drawable.presentred);
my_presents.add(R.drawable.presentyellow);
int choice = rand.nextInt(my_presents.size());
mBitmap = BitmapFactory.decodeResource(res, my_presents.get(choice));
mX = x + 50;
mY = y + 100;
mSpeedY = 5;
}
public void doDraw(Canvas canvas) {
canvas.drawBitmap(mBitmap, mX, mY, null);
}
public boolean animate(long elapsedTime) {
mY += mSpeedY * (elapsedTime / 20f);
boolean remove = checkBorders();
if (remove) {
return true;
}
return false;
}
private boolean checkBorders() {
if (mY + mBitmap.getHeight() >= Panel.mHeight) {
return true;
// mSpeedY = -mSpeedY;
// mY = Panel.mHeight - mBitmap.getHeight();
}
return false;
}
}
Any help is appreciated.

I think these lines may cause a problem:
for (Present presents : mPresents) {
boolean remove = presents.animate(elapsedTime);
if (remove) {
mPresents.remove(presents);
}
}
Since you are trying to remove "presents" from the "mPresents", while you are on that element of the list. I could be wrong, but I think this is a bit like trying to eat your own head. It might help to create another list (or just another Present object), and then remove that from the list after the loop is finished. For example, something like this:
ArrayList <Present> presentsToRemove = new ArrayList<Present>();
for (Present presents : mPresents) {
if (presents.animate(elapsedTime)) {
presentsToRemove.add(presents);
}
}
mPresents.removeAll(presentsToRemove);
Please let me know if this helps, or if I've misunderstood.

Related

drawImage is not applicable for the arguments

Look I'm going to be up front about this. My assignment is due soon and i've spent way too many hours trying to fix this problem with no success at all. I'm essentially clueless at what the issue is and I really dont know where to look. I have 5 classes, I will try and post them all to ensure I get the answer, I am unable to change GameManager or Goal but I am allowed to change any other class.
The problem lines are this.canvasGraphics.drawImage(player.getCurrentImage() where drawImage says it isnt applicable for the arguments
and
this.enemies[i].getX() - (this.enemies[i].getCurrentImage().getWidth() / 2),
this.enemies[i].getY() - (this.enemies[i].getCurrentImage().getHeight() / 2), null);
where getWidth and getHeight show an almost identical error
thanks in advance
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.awt.Font;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class GameManager extends JFrame implements KeyListener {
private int canvasWidth;
private int canvasHeight;
private int borderLeft;
private int borderTop;
private BufferedImage canvas;
private Stage stage;
private Enemy[] enemies;
private Player player;
private Goal goal;
private Graphics gameGraphics;
private Graphics canvasGraphics;
private int numEnemies;
private boolean continueGame;
public static void main(String[] args) {
// During development, you can adjust the values provided in the brackets below
// as needed. However, your code must work with different/valid combinations
// of values.
int choice;
do{
GameManager managerObj = new GameManager(1920, 1080);
choice=JOptionPane.showConfirmDialog(null,"Play again?", "", JOptionPane.OK_CANCEL_OPTION);
}while(choice==JOptionPane.OK_OPTION);
System.exit(0);
}
public GameManager(int preferredWidth, int preferredHeight) {
int maxEnemies;
try{
maxEnemies=Integer.parseInt(JOptionPane.showInputDialog("How many enemies? (Default is 5)"));
if (maxEnemies<0)
maxEnemies=5;
}
catch (Exception e){
maxEnemies=5;
}
this.borderLeft = getInsets().left;
this.borderTop = getInsets().top;
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
if (screenSize.width < preferredWidth)
this.canvasWidth = screenSize.width - getInsets().left - getInsets().right;
else
this.canvasWidth = preferredWidth - getInsets().left - getInsets().right;
if (screenSize.height < preferredHeight)
this.canvasHeight = screenSize.height - getInsets().top - getInsets().bottom;
else
this.canvasHeight = preferredHeight - getInsets().top - getInsets().bottom;
setSize(this.canvasWidth, this.canvasHeight);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
addKeyListener(this);
Random rng = new Random();
this.canvas = new BufferedImage(this.canvasWidth, this.canvasHeight, BufferedImage.TYPE_INT_RGB);
// Create a Stage object to hold the background images
this.stage = new Stage();
// Create a Goal object with its initial x and y coordinates
this.goal = new Goal((Math.abs(rng.nextInt()) % (this.canvasWidth)),
(Math.abs(rng.nextInt()) % this.canvasHeight));
// Create a Player object with its initial x and y coordinates
this.player = new Player((Math.abs(rng.nextInt()) % (this.canvasWidth)),
(Math.abs(rng.nextInt()) % this.canvasHeight));
// Create the Enemy objects, each with a reference to this (GameManager) object
// and their initial x and y coordinates.
this.numEnemies = maxEnemies;
this.enemies = new Enemy[this.numEnemies];
for (int i = 0; i < this.numEnemies; i++) {
this.enemies[i] = new Enemy(this, Math.abs(rng.nextInt()) % (this.canvasWidth),
Math.abs(rng.nextInt()) % this.canvasHeight);
}
this.gameGraphics = getGraphics();
this.canvasGraphics = this.canvas.getGraphics();
this.continueGame = true;
long gameStartTime=System.nanoTime();
while (this.continueGame) {
updateCanvas();
}
this.stage.setGameOverBackground();
double gameTime=(System.nanoTime()-gameStartTime)/1000000000.0;
updateCanvas();
this.gameGraphics.setFont(new Font(this.gameGraphics.getFont().getFontName(), Font.PLAIN, 50));
if (gameTime<1)
this.gameGraphics.drawString("Oops! Better luck next time...", this.canvasWidth/3, this.canvasHeight/2 - 50);
else
this.gameGraphics.drawString("You survived " + String.format("%.1f", gameTime)+ " seconds with "+this.numEnemies+" enemies!",
this.canvasWidth/4, this.canvasHeight/2 - 50);
return;
}
public void updateCanvas() {
long start = System.nanoTime();
this.goal.performAction();
// If the player is alive, this should move the player in the direction of the
// key that has been pressed
// Note: See keyPressed and keyReleased methods in the GameManager class.
this.player.performAction();
// If the enemy is alive, the enemy must move towards the Player. The Player object
// is obtained via the GameManager object that is given at the time of creating an Enemy
// object.
// Note: The amount that the enemy moves by must be much smaller than that of
// the player above or else the game becomes too hard to play.
for (int i = 0; i < this.numEnemies; i++) {
this.enemies[i].performAction();
}
if ((Math.abs(this.goal.getX() - this.player.getX()) < (this.goal.getCurrentImage().getWidth() / 2))
&& (Math.abs(this.goal.getY() - this.player.getY()) < (this.goal.getCurrentImage().getWidth() / 2))) {
for (int i = 0; i < this.numEnemies; i++) {
// Sets the image of the enemy to the "dead" image and sets its status to
// indicate dead
this.enemies[i].die();
}
// Sets the background of the stage to the finished game background.
this.stage.setGameOverBackground();
this.continueGame = false;
}
// If an enemy is close to the player or the goal, the player and goal die
int j = 0;
while (j < this.numEnemies) {
if ((Math.abs(this.player.getX() - this.enemies[j].getX()) < (this.player.getCurrentImage().getWidth() / 2))
&& (Math.abs(this.player.getY() - this.enemies[j].getY()) < (this.player.getCurrentImage().getWidth()
/ 2))) {
this.player.die();
this.goal.die();
this.stage.setGameOverBackground();
j = this.numEnemies;
this.continueGame = false;
}
else if ((Math.abs(this.goal.getX() - this.enemies[j].getX()) < (this.goal.getCurrentImage().getWidth() / 2))
&& (Math.abs(this.goal.getY() - this.enemies[j].getY()) < (this.goal.getCurrentImage().getWidth()
/ 2))) {
this.player.die();
this.goal.die();
this.stage.setGameOverBackground();
j = this.numEnemies;
this.continueGame = false;
}
j++;
}
try {
// Draw stage
this.canvasGraphics.drawImage(stage.getCurrentImage(), 0, 0, null);
// Draw goal
this.canvasGraphics.drawImage(this.goal.getCurrentImage(),
this.goal.getX() - (this.goal.getCurrentImage().getWidth() / 2),
this.goal.getY() - (this.goal.getCurrentImage().getHeight() / 2), null);
// Draw player
this.canvasGraphics.drawImage(player.getCurrentImage(),
this.player.getX() - (this.player.getCurrentImage().getWidth() / 2),
this.player.getY() - (this.player.getCurrentImage().getHeight() / 2), null);
// Draw enemies
for (int i = 0; i < this.numEnemies; i++) {
this.canvasGraphics.drawImage(this.enemies[i].getCurrentImage(),
this.enemies[i].getX() - (this.enemies[i].getCurrentImage().getWidth() / 2),
this.enemies[i].getY() - (this.enemies[i].getCurrentImage().getHeight() / 2), null);
}
} catch (Exception e) {
System.err.println(e.getMessage());
}
// Draw everything.
this.gameGraphics.drawImage(this.canvas, this.borderLeft, this.borderTop, this);
long end = System.nanoTime();
this.gameGraphics.setFont(new Font(this.gameGraphics.getFont().getFontName(), Font.PLAIN, 15));
this.gameGraphics.drawString("FPS: " + String.format("%2d", (int) (1000000000.0 / (end - start))),
this.borderLeft + 50, this.borderTop + 75);
return;
}
public Player getPlayer() {
return this.player;
}
public void keyPressed(KeyEvent ke) {
// Below, the setKey method is used to tell the Player object which key is
// currently pressed.
// The Player object must keep track of the pressed key and use it for
// determining the direction
// to move.
// Important: The setKey method in Player must not move the Player.
if (ke.getKeyCode() == KeyEvent.VK_LEFT)
this.player.setKey('L', true);
if (ke.getKeyCode() == KeyEvent.VK_RIGHT)
this.player.setKey('R', true);
if (ke.getKeyCode() == KeyEvent.VK_UP)
this.player.setKey('U', true);
if (ke.getKeyCode() == KeyEvent.VK_DOWN)
this.player.setKey('D', true);
if (ke.getKeyCode() == KeyEvent.VK_ESCAPE)
this.continueGame = false;
return;
}
#Override
public void keyReleased(KeyEvent ke) {
// Below, the setKey method is used to tell the Player object which key is
// currently released.
// The Player object must keep track of the pressed key and use it for
// determining the direction
// to move.
// Important: The setKey method in Player must not move the Player.
if (ke.getKeyCode() == KeyEvent.VK_LEFT)
this.player.setKey('L', false);
if (ke.getKeyCode() == KeyEvent.VK_RIGHT)
this.player.setKey('R', false);
if (ke.getKeyCode() == KeyEvent.VK_UP)
this.player.setKey('U', false);
if (ke.getKeyCode() == KeyEvent.VK_DOWN)
this.player.setKey('D', false);
return;
}
#Override
public void keyTyped(KeyEvent ke) {
return;
}
}
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.util.*;
public class Goal {
private int x;
private int y;
private BufferedImage imageCurrent;
private BufferedImage imageRunning;
private BufferedImage imageOver;
private int stepSize;
private Random rng; // Tip: Code that students write must not use randomness
public Goal(int x, int y) {
try {
this.imageRunning = ImageIO.read(new File("goal-alive.png"));
this.imageOver = ImageIO.read(new File("goal-dead.png"));
} catch (IOException e) {
e.printStackTrace();
}
this.x = x;
this.y = y;
this.stepSize = 10;
this.rng = new Random(x + y); // Tip: Code that students write (elsewhere) must not use any randomness.
this.imageCurrent = this.imageRunning;
return;
}
public void performAction() {
// The code below shows how the Goal can be moved by manipulating its x and y
// coordinates.
// Tip: Code that students write (elsewhere) must not use any randomness.
this.x += this.rng.nextInt() % stepSize;
this.y += this.rng.nextInt() % stepSize;
return;
}
public int getY() {
return this.y;
}
public int getX() {
return this.x;
}
public BufferedImage getCurrentImage() {
return this.imageCurrent;
}
public void die() {
this.imageCurrent = this.imageOver;
return;
}
}
import java.awt.Image;
public class Enemy {
private Image CurrentImage;
private int x;
private int y;
public Enemy(GameManager gameManager, int x, int y) {
}
public void performAction() {
}
public void die() {
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public Image getCurrentImage() {
return CurrentImage;
}
}
import java.awt.Dimension;
public class Player {
private Dimension CurrentImage;
private int x;
private int y;
public Player(int x1, int y1) {
}
public void performAction() {
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public Dimension getCurrentImage() {
return CurrentImage;
}
public void die() {
}
public void setKey(char c, boolean b) {
}
}
import java.awt.Image;
public class Stage {
public void setGameOverBackground() {
}
public Image getCurrentImage() {
return null;
}
}
Player.getCurrentImage() returns a Dimension, not an Image.

How do I embed this into my website?

I am attempting to embed a game into my website that I programmed in java. I have no idea how to take my code from eclipse(which is what my JDE is) and put it into my website. I am using a weebly.com website. I do have several unfinished classes, I want to upload my incomplete games as well as complete just to show progress. so I ask you, how do I get this code from eclipse, to my website. Thanks for the help and the following is my code.
This is my Main class:
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
public class Main extends Applet implements Runnable {
private static final long serialVersionUID = 1L;
Thread th = new Thread(this);
boolean running = true;
public int Jweidth = 400, Jheight = 400;
Image dbImage;
Graphics dbGraphics;
Bullet b;
Player p;
Enemy e, e2, e3, e4, e5, e6, e7, e8;
HealthBar hb;
NameSign ns;
Restart r;
private boolean BFire;
public void init() {
//set window size
setSize(Jweidth, Jheight);
//calls player class
p = new Player(this);
//calls healthBar
hb = new HealthBar(this, p);
//calls enemy class
e = new Enemy(this);
e2 = new Enemy(42, 0, this);
e3 = new Enemy(84, 0, this);
e4 = new Enemy(126, 0, this);
e5 = new Enemy(0, 42, this);
e6 = new Enemy(42, 42, this);
e7 = new Enemy(84, 42, this);
e8 = new Enemy(126, 42, this);
//calls bullet class
b = new Bullet(this);
//calls nameSign class
ns = new NameSign(this);
//calls Restart class
r = new Restart(this);
}
public void start() {
//starts a new thread
th.start();
}
public void stop() {
running = false;
}
public void destroy() {
running = false;
}
public void run() {
while (running) {
setBFire(b.getFire());
//calls update method from player class
p.update(this);
//calls update method from enemy class
e.update(this, p);
e2.update(this, p);
e3.update(this, p);
e4.update(this, p);
e5.update(this, p);
e6.update(this, p);
e7.update(this, p);
e8.update(this, p);
//calls update method from fire class if BFire is true
if (setBFire(true)) {
b.update(this, p);
}
//calls update method from HealthBar class
hb.update(this, p);
//calls update method from NameSign class
ns.update(this);
//calls update method from Restart class
r.update(this, p);
repaint();
//sets Thread to repeat every 17 milliseconds
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//doublebuffer
public void update(Graphics g) {
dbImage = createImage(Jweidth, Jheight);
dbGraphics = dbImage.getGraphics();
paint(dbGraphics);
g.drawImage(dbImage, 0, 0, this);
}
//paint class
public void paint(Graphics g) {
//calls paint method from player class
p.paint(g, this);
//calls paint method from enemy class
e.paint(g, this);
e2.paint(g, this);
e3.paint(g, this);
e4.paint(g, this);
e5.paint(g, this);
e6.paint(g, this);
e7.paint(g, this);
e8.paint(g, this);
//calls paint method from bullet class
b.paint(g, this);
//calls paint method from healthBar class
hb.paint(g, this);
//calls paint method from nameSign class
ns.paint(g, this);
//calls paint method from Restart class
r.paint(g);
}
public int getJweidth() {
return Jweidth;
}
public int getJheight() {
return Jheight;
}
//ignore all boolean Bfire methods
public boolean isBFire() {
return BFire;
}
public boolean setBFire(boolean bFire) {
BFire = bFire;
return bFire;
}
}
This is my Enemy class:
import java.awt.*;
import java.net.URL;
public class Enemy {
//Enemy ints
private int x = 0, y = 0, speed = 2;
private URL url;
private Image Enemy;
//adds image
public Enemy(Main m){
url = m.getDocumentBase();
Enemy = m.getImage(url, "Enemy.png");
}
public Enemy(int i, int j, Main m) {
url = m.getDocumentBase();
Enemy = m.getImage(url, "Enemy.png");
x = i;
y = j;
}
//same as run method but just for the enemy
public void update(Main m, Player p){
x += speed;
if(x <= 0){
speed = 2;
y += 32;
}
else if(x > m.getJweidth() - 32){
speed = -2;
y += 32;
}
//calls collision method
collision(p);
}
//enemy player hitbox
private void collision(Player p) {
int Px = p.getX();
int Py = p.getY();
int Pr = p.getRadious();
if(Px - Pr <= x && Px + Pr >= x && Py - Pr <= y && Py + Pr >= y){
p.hit();
}
}
//Graphics for enemy
public void paint(Graphics g, Main m){
g.drawImage(Enemy, x, y, m);
}
}
This is my Bullet class (this game is a work in progress and this class isn't working, but that is just unfinished work that I will do soon)
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.net.URL;
public class Enemy {
//Enemy ints
private int x = 0, y = 0, speed = 2;
private URL url;
private Image Enemy;
//adds image
public Enemy(Main m) {
url = m.getDocumentBase();
Enemy = m.getImage(url, "Enemy.png");
}
public Enemy(int i, int j, Main m) {
url = m.getDocumentBase();
Enemy = m.getImage(url, "Enemy.png");
x = i;
y = j;
}
//same as run method but just for the enemy
public void update(Main m, Player p) {
x += speed;
if (x <= 0) {
speed = 2;
y += 32;
} else if (x > m.getJweidth() - 32) {
speed = -2;
y += 32;
}
//calls collision method
collision(p);
}
//enemy player hitbox
private void collision(Player p) {
int Px = p.getX();
int Py = p.getY();
int Pr = p.getRadious();
if (Px - Pr <= x && Px + Pr >= x && Py - Pr <= y && Py + Pr >= y) {
p.hit();
}
}
//Graphics for enemy
public void paint(Graphics g, Main m) {
g.drawImage(Enemy, x, y, m);
}
}
This is my Restart class(once again unfinished but on the way)
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Restart implements KeyListener {
private int x, y;
private int pHealth;
private String string = "Would you like to play again?";
private boolean restart = false;
public Restart(Main m) {
x = 600;
y = 600;
}
public void update(Main m, Player p) {
//checks if players health = 0 and if restart is true
pHealth = p.getpHealth();
if (setRestart(true && pHealth <= 0)) {
System.out.println("Restart");
x = m.Jweidth / 2 - 75;
y = m.Jheight / 2;
}
//reset ints for player
//TODO
//reset ints for enemy
//TODO
//reset ints for bullet
//TODO
//reset ints for healthbar
//TODO
}
public void paint(Graphics g) {
g.drawString(string, x, y);
}
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_F1: {
setRestart(true);
break;
}
}
}
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_F1: {
setRestart(false);
break;
}
}
}
public void keyTyped(KeyEvent arg0) {
}
//ignore all boolean methods
public boolean isRestart() {
return restart;
}
public boolean setRestart(boolean restart) {
this.restart = restart;
return restart;
}
}
You will have to use Applets to embed your Java program in a browser, or Java Web Start if you just want to start it from the web in a new window.
Some security issues may apply depending on the Java version you are using.
Here are some examples on how to do it:
https://docs.oracle.com/javase/tutorial/deployment/applet/
http://www.javatpoint.com/java-applet
And here for the Java Web Start:
https://docs.oracle.com/javase/tutorial/deployment/webstart/
You're gonna need to make a .jar file and a compiled .class file, no .java file. To implement Java code in HTML, you can use the deprecated <applet> tag, or the new <object> tag.
<object codetype="application/java" classid="java:yourclass.class" archive="yourjar.jar" width="1000" height="1000"></object>
codetype="application/java" - The type of code, use application/java.
classid="?" - Java class to run, eg. java:MyApplet.class
archive="url" - Address or filename of the Java archive file (.jar) containing the class files.
width="?" - The width of the window, in pixels.
height="?" - The height of the window, in pixels.
Just telling you, I'm not sure that it'll work.

How can I make each block move in the opposite direction once they reach a certain point on the side of the screen?

I am trying to get three different blocks to move back and forth from one side of the screen to the other. If the block on the far right reaches the game frame's width, it's velocity is reversed and it starts moving to the left side. However, my problem exists with the other two blocks. I put in my code a method that states once the second block reaches the (game width - 100), with 100 just being the width of each blocks, it's velocity should be reversed. The third block is suppose to work the same except once it reaches the x point (game width - 200). My attempt to change the velocity of the second and third blocks can be seen under the UpdateBlocks method in the PlayState class posted below.
Another thing I want to point out is that in update method in the block class, the x value is being reversed too. I tried at first to make it read the blocks from the PlayState then change the corresponding velocities but I got a thread error. That's why I am bringing my current predicament to you.
Here is the block class:
package com.jamescho.game.model;
import java.awt.Rectangle;
import com.jamescho.framework.util.RandomNumberGenerator;
import com.jamescho.game.main.GameMain;
import com.jamescho.game.state.PlayState;
public class Block {
private float x, y;
private int width, height, velX = 700;
private Rectangle rect;
private PlayState play;
private boolean visible;
private static final int UPPER_Y = 275;
private static final int LOWER_Y = 355;
public Block(float x, float y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
rect = new Rectangle((int) x, (int) y, width, height);
visible = false;
}
// Note: Velocity value will be passed in from PlayState!
public void update(float delta) {
x += velX * delta;
if (x <= 0 || x >= GameMain.GAME_WIDTH - 100) {
velX = -velX;
}
updateRect();
}
public void updateRect() {
rect.setBounds((int) x, (int) y, width, height);
}
public void invisible() {
visible = false;
}
public void visible() {
visible = true;
}
public void stop() {
velX = 0;
}
public void reverse() {
velX = -velX;
}
public float getX() {
return x;
}
public float getY() {
return y;
}
public boolean isVisible() {
return visible;
}
public Rectangle getRect() {
return rect;
}
}
Here is the PlayState where everything is going on:
package com.jamescho.game.state;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import com.jamescho.game.main.GameMain;
import com.jamescho.game.main.Resources;
import com.jamescho.game.model.Block;
public class PlayState extends State {
private ArrayList<Block> row1;
private ArrayList<Block> row2;
private ArrayList<Block> row3;
private Block block;
private Font scoreFont;
private int playerScore = 0;
private static final int BLOCK_HEIGHT = 100;
private static final int BLOCK_WIDTH = 100;
private int blockSpeed = -200;
private static final int PLAYER_WIDTH = 66;
private static final int PLAYER_HEIGHT = 92;
#Override
public void init() {
row1 = new ArrayList<Block>();
row2 = new ArrayList<Block>();
scoreFont = new Font("SansSerif", Font.BOLD, 25);
for (int i = 0; i < 3; i++) {
Block b = new Block(i * 105, GameMain.GAME_HEIGHT - 101,
BLOCK_WIDTH, BLOCK_HEIGHT);
row1.add(b);
b.visible();
for (int h = 0; h < 3; h++) {
Block b2 = new Block(h * 105, b.getY() - 208,
BLOCK_WIDTH, BLOCK_HEIGHT);
row2.add(b2);
b2.invisible();
}
}
}
#Override
public void update(float delta) {
playerScore += 1;
if (playerScore % 500 == 0 && blockSpeed > -280) {
blockSpeed -= 10;
}
Resources.runAnim.update(delta);// starts iterating through its frames
updateBlocks(delta);
}
private void updateBlocks(float delta) { // time from last update
for (Block b : row1) { //foreach statement; for each iteration of "b" the code is executed, one "b" at a time
if(row1.get(1).getX() == GameMain.GAME_WIDTH - BLOCK_WIDTH - 5) {
row1.get(1).reverse();
}
else if(row1.get(2).getX() == GameMain.GAME_WIDTH - 2 * BLOCK_WIDTH - 5) {
row1.get(2).reverse();
}
b.update(delta);
}
for (Block c : row2) { //foreach statement; for each iteration of "b" the code is executed, one "b" at a time
// used with objects; can't use primitive
c.update(delta);
if (c.isVisible()) {
}
}
}
#Override
public void render(Graphics g) {
g.setColor(Color.BLACK);
g.fillRect(0, 0, GameMain.GAME_WIDTH, GameMain.GAME_HEIGHT);
renderPlayer(g);
renderBlocks(g);
renderScore(g);
}
private void renderScore(Graphics g) {
g.setFont(scoreFont);
g.setColor(Color.GRAY);
g.drawString("" + playerScore / 100, 20, 30);
}
private void renderPlayer(Graphics g) {
}
private void renderBlocks(Graphics g) {
for (Block b : row1) {
if (b.isVisible()) {
g.drawImage(Resources.blue_panel, (int) b.getX(), (int) b.getY(),
BLOCK_WIDTH, BLOCK_HEIGHT, null); // change null if you want the object to know about object
}
}
for (Block c : row2) {
if (c.isVisible()) {
g.drawImage(Resources.blue_panel, (int) c.getX(), (int) c.getY()+105,
BLOCK_WIDTH, BLOCK_HEIGHT, null); // change null if you want the object to know about object
}
}
}
#Override
public void onClick(MouseEvent e) {
}
#Override
public void onKeyPress(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
for (Block b : row1) {
b.stop();
for (Block c : row2) {
if (c.isVisible() == true) {
c.stop();
}
}
}
}
else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
}
}
#Override
public void onKeyRelease(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_SPACE) {
for (Block c: row2) {
c.visible();
}
}
}
public float getb1X() {
return row1.get(1).getX();
}
}
Sorry I haven't gone through your entire code. But this is how I would do it:
int x , int y -- are the coordinates of each block on the screen.
a block can move on the screen in 4 ways / directions / quadrants:
1) x = x + deltaX, y = y + deltaY
2) x = x - deltaX, y = y + deltaY
3) x = x + deltaX, y = y - deltaY
4) x = x - deltaX, y = y - deltaY
Thus in order to change the direction when a block hits any side you should multiply deltaX with -1 if it hits left or right side and deltaY with -1 if it hits the bottom or top. this will reverse its direction.

thread doesn't update an array

I'm trying to make a program with graphs and print the graph on the screen. I am using the GraphPainter (a SurfaceView type, implements Runnable) class to paint the graph to the screen. In the drawing function, which loops indefinitely, i am updating the elements of the graph: the node list and the edge list from the Graph class. The node list is perfectly updated from the Graph (when i delete, add or select a node), but the edge list in the Painter don't update if I delete an edge from the actual Graph.
I debugged it and the graphEdgeList from the Graph class is updated correctly when I remove an edge. It's size gets lower. Can anybody tell me why isn't the list from GraphPainter updated accordingly?
GraphDrawer.java:
package com.rares.graphit;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.view.WindowManager;
public class GraphDrawer extends Activity implements OnTouchListener{
/**Suface Manipulator*/
GraphPainter gp;
/**Graph object*/
public static Graph graph = null;
/**Touch coordinates*/
public static float touchX = 0;
public static float touchY = 0;
/**Drag state*/
public boolean isDragging = false;
/**Drag coordinates*/
public static float dragX = 0;
public static float dragY = 0;
/**Id of the node that is currently selected
* Is -1 if no node is selected during a touch event*/
public static int currentId = -1;
/**Id of a node that was selected before and an action between 2 nodes or on a node
* that needs to be deleted or moved*/
public static int firstId = -1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*Set window to fullscreen**/
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
gp = new GraphPainter(this);
gp.setOnTouchListener(this);
graph = new Graph();
setContentView(gp);
}
#Override
public boolean onTouch(View view, MotionEvent event) {
// TODO Auto-generated method stub
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
touchX = event.getX();
touchY = event.getY();
currentId = graph.pointIntersectsNode(touchX, touchY);
break;
case MotionEvent.ACTION_MOVE:
dragX = event.getX();
dragY = event.getY();
/**Function will return -1 if there is no intersection or node ID if drag start intersects the node*/
/**Selected node will be red on the screen*/
if ((dragX - touchX)*(dragX - touchX) + (dragY - touchY)*(dragY - touchY) > Graph.Circle.RADIUS_DEFAULT){
if(currentId != -1){
graph.setNodePosition(currentId, dragX, dragY);
}
isDragging = true;
}
break;
case MotionEvent.ACTION_UP:
if(!isDragging){
if(currentId == -1)
graph.addNode(touchX, touchY);
else{
if(!graph.getGraphNodeList().get(currentId).isSelected){
graph.markNodeAsSelected(currentId);
if(firstId == -1)
firstId = currentId;
else{
if(graph.isEdge(Math.min(firstId, currentId), Math.max(firstId, currentId))){
graph.deleteEdge(Math.min(firstId,currentId),Math.max(firstId, currentId));
}
graph.addEdge(Math.min(firstId,currentId),Math.max(firstId, currentId));
graph.markNodeAsDeselected(currentId);
graph.markNodeAsDeselected(firstId);
firstId = -1;
}
}
else{
Log.d("IDS", "ID1: " + Integer.toString(currentId) + "\nSelected: " + Integer.toString(firstId));
/*graph.markNodeAsDeselected(id1);*/
if(firstId == currentId){
graph.deleteNode(currentId);
}
currentId = -1;
firstId = -1;
}
}
}
/*else
if(id != -1){
graph.markNodeAsDeselected(id);
id = -1;
}*/
//Reset values
isDragging = false;
touchX = touchY = dragX = dragY = 0;
break;
}
return true;
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
gp.resume();
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
gp.pause();
}
}
GraphPainter.java:
package com.rares.graphit;
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class GraphPainter extends SurfaceView implements Runnable {
/**ArrayLists for drawing the elements of the graph*/
ArrayList<Graph.Node> listNode;
ArrayList<Graph.Edge> listEdge;
/**Holder of surface*/
SurfaceHolder holder;
/**Drawing thread*/
Thread drawThread;
/**Canvas for drawing*/
Canvas canvas = null;
/**Bool for running state*/
boolean isRunning = false;
public GraphPainter(Context context){
super(context);
holder = getHolder();
drawThread = new Thread(this);
isRunning = true;
drawThread.start();
}
#Override
public void run(){
while (isRunning) {
if (holder.getSurface().isValid()) {
canvas = holder.lockCanvas();
/**Draw background*/
canvas.drawRGB(255, 255, 255);
/**Draw Graph*/
drawGraph();
/**Print to screen*/
holder.unlockCanvasAndPost(canvas);
}
}
}
public void drawGraph(){
/**Draw Egdes*/
listEdge = GraphDrawer.graph.getGraphEdgeList();
Log.d("PAINT_EDGES", "Size of listEdge: " + listEdge.size());
for(int i = 0; i < listEdge.size(); ++i){
float startX = listNode.get(listEdge.get(i).id1).drawingCircle.x;
float startY = listNode.get(listEdge.get(i).id1).drawingCircle.y;
float stopX = listNode.get(listEdge.get(i).id2).drawingCircle.x;
float stopY = listNode.get(listEdge.get(i).id2).drawingCircle.y;
Paint linePaint = new Paint();
linePaint.setColor(Graph.NODE_COLOR_UNSELECTED);
canvas.drawLine(startX, startY, stopX, stopY, linePaint);
}
/**Draw Nodes*/
listNode = GraphDrawer.graph.getGraphNodeList();
for(int i = 0; i < listNode.size(); ++i){
canvas.drawCircle(listNode.get(i).drawingCircle.x, listNode.get(i).drawingCircle.y, listNode.get(i).drawingCircle.R, listNode.get(i).drawingCircle.circlePaint);
}
/*clear the arraylists**/
/*listNode.clear();
listEdge.clear();*/
}
/**Will be called from GraphDrawer when onPause() will occur*/
public void pause(){
isRunning = false;
try {
drawThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
drawThread = null;
}
public void resume(){
drawThread = new Thread(this);
isRunning = true;
drawThread.start();
}
}
Graph.java:
package com.rares.graphit;
import java.util.ArrayList;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.Log;
/**Graph structure and manipulator. Momentarily, it will be an unoriented graph*/
public class Graph {
/**Circle for drawing purposes*/
public static class Circle{
/**Circle Radius setting*/
public static final float RADIUS_DEFAULT = 30;
/**Circle coordinates*/
float x, y;
float R;
/**Circle style*/
Paint circlePaint = null;
/*Circle default color*/
public int DEFAULT_COLOR = Color.BLUE;
public int drawColor;
/**Creates a circle with the Point as center, r as radius, and the default color
* of a node*/
public Circle(float x, float y, float r){
this.x = x;
this.y = y;
this.R = r;
this.circlePaint = new Paint();
this.circlePaint.setColor(DEFAULT_COLOR);
drawColor = DEFAULT_COLOR;
}
}
/**Graph node structure*/
public static class Node{
/**For drawing purposes*/
Circle drawingCircle;
/**Node ID in the graph*/
int ID;
/**Flag that shows wether the node is selected*/
public boolean isSelected = false;
public Node(float x, float y){
this.ID = numberOfNodes;
drawingCircle = new Circle(x, y, Circle.RADIUS_DEFAULT);
}
public void setColor(int color){
this.drawingCircle.circlePaint.setColor(color);
}
}
/**Graph edge structure*/
public static class Edge{
/**Nodes between whom the edge will be drawn
* id1 - the lower number
* id2 - the higher number
* */
public int id1, id2;
/**Constructor that will set the nodes of the edge*/
public Edge(int a, int b){
if(a > b){
id1 = b; id2 = a;
}
else{
id1 = a; id2 = b;
}
}
}
/**List of vicinity of the graph*/
public static ArrayList<Node> graphNodeList;
/**Current number of nodes*/
public static int numberOfNodes = 0;
/**List of the edges of the graph*/
public static ArrayList<Edge> graphEdgeList;
/**Node default colors*/
public static int NODE_COLOR_UNSELECTED = Color.BLUE;
public static int NODE_COLOR_SELECTED = Color.RED;
/**All elements will be added through addNode() or addEdge() methods*/
public Graph(){
graphNodeList = new ArrayList<Graph.Node>(0);
graphEdgeList = new ArrayList<Graph.Edge>(0);
}
/**List of vicinity getter*/
public ArrayList<Node> getGraphNodeList(){
return graphNodeList;
}
/**List of Edges getter*/
public ArrayList<Edge> getGraphEdgeList(){
return graphEdgeList;
}
/**Adds a node into the graph, with the canvas coordinates: x and y*/
public void addNode(float x, float y){
Node newNode = new Node(x, y);
newNode.ID = graphNodeList.size();
graphNodeList.add(newNode);
newNode = null;
}
/**Deletes a node from the graph */
void deleteNode(int id){
graphNodeList.remove(id);
deleteEdges(id);
for(int i = id; i < graphNodeList.size(); ++i){
int aux = graphNodeList.get(i).ID;
if(aux != i)
resetEdgeNodes(aux, i);
graphNodeList.get(i).ID = i;
}
}
/**Verifies if a point described by its coordinates intersects one if the nodes on
* the screen.
* Returns the ID of the node if true
* -1 otherwise*/
public int pointIntersectsNode(float X, float Y){
for(int i = 0; i < graphNodeList.size(); i++){
float centerX = graphNodeList.get(i).drawingCircle.x;
float centerY = graphNodeList.get(i).drawingCircle.y;
float circleRadius = graphNodeList.get(i).drawingCircle.R;
if((centerX-X) * (centerX-X) + (centerY-Y)*(centerY-Y) < circleRadius*circleRadius)
return i;
}
return -1;
}
/**Marks node as selected and will paint it the COLOR_SELECTED color*/
public void markNodeAsSelected(int id){
graphNodeList.get(id).setColor(NODE_COLOR_SELECTED);
graphNodeList.get(id).isSelected = true;
}
/**Marks the node back as deselected, with its default color*/
public void markNodeAsDeselected(int id) {
graphNodeList.get(id).drawingCircle.circlePaint.setColor(NODE_COLOR_UNSELECTED);
graphNodeList.get(id).isSelected = false;
}
/**Sets the position of the node with the id ID at the (X,Y) point*/
public void setNodePosition(int id, float X, float Y) {
graphNodeList.get(id).drawingCircle.x = X;
graphNodeList.get(id).drawingCircle.y = Y;
}
/**Adds an edge between two nodes*/
public void addEdge(int id1, int id2){
Edge edge = new Edge(id1, id2);
graphEdgeList.add(edge);
}
/**Verifies if an edge between nodes id1 and id2 exists*/
public boolean isEdge(int id1, int id2){
for(int i = 0; i < graphEdgeList.size(); ++i){
if(id1 == graphEdgeList.get(i).id1 && id2 == graphEdgeList.get(i).id2)
return true;
}
return false;
}
/**Deletes an edge from the list, by the nodes IDs
* id1 is the node with the minimum id
* id2 is the node with the maximum id
* */
public void deleteEdge(int id1, int id2){
Log.d("EDGE_DELETE", "Size before a single edge deletion: " + Integer.toString(graphEdgeList.size()));
for(int i = 0; i < graphEdgeList.size(); ++i)
if(id1 == graphEdgeList.get(i).id1 && id2 == graphEdgeList.get(i).id2){
Log.d("EDGE", "EDGE DELETED" + Integer.toString(id1) + " " + Integer.toString(id2));
graphEdgeList.remove(i);
Log.d("EDGE_DELETE", "Size after a single edge deletion: " + Integer.toString(graphEdgeList.size()));
return;
}
}
/**Deletes the edges which has one of the nodes with its ID set to id*/
public void deleteEdges(int id){
for(int i = 0; i < graphEdgeList.size(); ++i){
if(id == graphEdgeList.get(i).id1 || id == graphEdgeList.get(i).id2){
graphEdgeList.remove(i);
i--;
}
}
}
/**Resets the List of Edges when a node is deleted*/
public void resetEdgeNodes(int oldId, int newId){
for(int i = 0; i < graphEdgeList.size(); ++i){
int nodeId1 = graphEdgeList.get(i).id1;
int nodeId2 = graphEdgeList.get(i).id2;
if(nodeId1 == oldId){
graphEdgeList.get(i).id1 = newId;
}
else
if(nodeId2 == oldId){
graphEdgeList.get(i).id2 = newId;
}
/*If the new nodes are nod in order, swap them**/
if(graphEdgeList.get(i).id1 > graphEdgeList.get(i).id2){
int aux = graphEdgeList.get(i).id1;
graphEdgeList.get(i).id1 = graphEdgeList.get(i).id2;
graphEdgeList.get(i).id2 = aux;
}
}
}
}
The main problem you are running into is a common issue in multithreaded programming. In java, two of the concerns you need to address are the safety of accessing the graph object from one thread while modifying it from another.
The other concern is related in that both threads may have a different view of the graph object and measures must be taken to let the runtime/compiler know that after certain code boundaries, the view of the graph object must be synchronized.
It would likely help to research synchronized keyword and memory synchronizations. Of course other solutions/optimizations may exist, the best approach is to understand the multithreading concerns mentioned and first take the most straightforward solution .... Deal with performance / optimization later if possible.

onDraw(Canvas canvas) never reached?

Can anyone help, my app does not seem to do the onDraw() in the GraView class, even if .invalidate is called upon from either inside or outside the class. I managed to figure out with system.err that it does invalidate the view, however it never gets in the onDraw( ), even though the rest of the app keeps running. I found a lot of solutionssuggesting putting setWillNotDraw(false) in the constructor, but that did not solve anything.
GravIO.java File:
package dabawi.gravitas;
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
public class GravIO extends Activity implements Runnable, OnTouchListener {
public final static int clock = 1000;
private GravEngine engine;
private GraView TV;
private SensorManager mSensorManager;
private Sensor mSensor;
private Thread t1;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
t1 = new Thread(this);
t1.start();
engine = new GravEngine();
TV = new GraView(this, engine);
setContentView(TV);
TV.setOnTouchListener(this);
TV.setVisibility(View.VISIBLE);
//mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
System.err.println("Starting Engine") ;
run();
}
#Override
public void run() {
while (true) {
try {
System.err.println("Tik") ;
engine.tick();
TV.invalidate();
Thread.sleep(GravIO.clock);
} catch (InterruptedException ex) {
System.err.println("faal");
}
}
}
#Override
public boolean onTouch(View view, MotionEvent event) {
engine.switchGravity();
return true;
}
}
GraView.java File:
package dabawi.gravitas;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
#SuppressLint({ "DrawAllocation", "ViewConstructor" })
public class GraView extends View {
private GravEngine engine;
private int screenWidth, screenHeight, ySpace = 5, xSpace, scale;
private Paint paint;
private int xLoc, yLoc;
private boolean xWall = false, yWall = false;
public GraView(Context context, GravEngine engine) {
super(context);
setWillNotDraw(false);
this.engine = engine;
calcScale(context);
}
#Override // We think the problem is with this method, that it is never called upon.
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
System.err.println("Calculating position");
calcPos();
canvas = new Canvas();
// drawing background
paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
canvas.drawPaint(paint);
drawGame(canvas);
}
private void drawGame(Canvas canvas) {
drawRoom(canvas);
drawPlayer(canvas);
}
#SuppressWarnings("deprecation")
private void calcScale(Context context) {
WindowManager wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
Display d = wm.getDefaultDisplay();
screenWidth = d.getWidth();
screenHeight = d.getHeight();
scale = screenHeight / ySpace;
xSpace = screenWidth / scale;
}
private void calcPos() {
xLoc = (engine.getxPlayer() / GravEngine.roomScaling);
yLoc = (engine.getyPlayer() / GravEngine.roomScaling);
if (xLoc < (xSpace + 1) / 2) {
xLoc = (xSpace + 1) / 2;
xWall = true;
} else if (xLoc > (GravRoom.xSize - ((xSpace + 1) / 2))) {
xLoc = GravRoom.xSize - ((xSpace + 1) / 2);
xWall = true;
} else {
xWall = false;
}
if (yLoc < (ySpace + 1) / 2) {
yLoc = (ySpace + 1) / 2;
yWall = true;
} else if (yLoc > (GravRoom.xSize - ((ySpace + 1) / 2))) {
xLoc = GravRoom.ySize - ((ySpace + 1) / 2);
yWall = true;
} else {
yWall = false;
}
}
private void drawPlayer(Canvas canvas) {
float xPos = engine.getxPlayer() / GravEngine.roomScaling, yPos = engine
.getyPlayer() / GravEngine.roomScaling;
if (xWall) {
}
if (yWall) {
}
paint.setColor(Color.BLUE);
int left = (int) (xPos * scale), top = (int) (yPos * scale);
int right = left + (GravEngine.pxSize / GravEngine.roomScaling) * scale;
int bot = top + (GravEngine.pySize / GravEngine.roomScaling) * scale;
canvas.drawRect(left, top, right, bot, paint);
}
private void drawRoom(Canvas canvas) {
for (int i = 0, x = xLoc - ((xSpace + 1) / 2); i < xSpace + 1; x++, i++) {
for (int j = 0, y = yLoc - ((ySpace + 1) / 2); i < ySpace + 1; y++, j++) {
drawRoomPart(x,y,i,j,canvas);
}
}
}
private void drawRoomPart(int x, int y, int i, int j, Canvas canvas) {
if (x >= 0 && y >= 0 && x < GravRoom.xSize && y < GravRoom.ySize) {
short type = engine.getRoom(engine.getCurrentRoom()).getGridPos(x,y);
if (type != 0) {
drawBlock(canvas, i, x, j, y, type);
}
}
}
private void drawBlock(Canvas canvas, int i, int x, int j, int y, short type) {
int left = i * scale, top = y * scale;
int right = left + scale;
int bot = top + scale;
paint.setColor(colorBlock(type));
canvas.drawRect(left, top, right, bot, paint);
System.err.println("Left" + left + " top: " + top + " right: "
+ right + " bot: " + bot);
}
private int colorBlock(short type) {
if (type == 1) {
return Color.DKGRAY;
} else if (type == 2) {
return Color.CYAN;
} else if (type == 3) {
return Color.GREEN;
} else if (type == 4) {
return Color.RED;
} else {
return Color.MAGENTA;
}
}
// private void imageBlock(short type) {
//
// }
}
Ouch !
Your call to your run method is executed in the UIThread (as the onCreate method), and it's doing an infinite loop in it.
Just add a println after the call and you will see that the UI thread is never released, your application should not even start !
You don't see any changes because you are creating a new canvas and drawing on that. To fix this, remove the line
canvas = new Canvas();
Also, you should initiate your Paint outside of the onDraw method (this is an optimization recommended by the Android documentation).

Categories