Jump to content

O mesmo código Java bloqueia em pc's diferentes


alllright
 Share

Go to solution Solved by HappyHippyHippo,

Recommended Posts

Boa tarde pessoal,

Algo muito estranho está acontecendo no meu projecto Java 2D.

Projecto: Jogo 2D

IDE: Netbeans 8.0.2

PC antigo: P4 2.0GHz x86 / HDD 120GB / RAM 1.25GB / Versão Java: Version 8 update 40 (build 1.8.0_40-b26) / S.O. Windows XP SP3 sem ligação web

PC novo: PI7 2.4GHz 4700HQ x64 / 2 SSD's RAID 0 de 120GB cada / RAM 8GB / Versão Java: Version 8 update 45 (build 1.8.0_45-b14) / S.O. Windows 8.1 Pro com ligação web

Problema: Tenho um projecto de um jogo 2D que funciona direitinho no meu PC antigo mas não funciona no meu PC novo. O problema é que, no PC novo, sempre que aparece a mensagem "Try Again? (Y/N)" (quando um jogador perde, por exemplo) e a tecla "Y" é clicada o jogo bloqueia (não dá nenhum erro, nada, simplesmente bloqueia nesse ecrã). No PC antigo não tenho qualquer problema e funciona tudo bem, sem uma única alteração no código.

Poderá ser a função thread run() que está a ter problemas no novo processador? Mesmo que seja será estranho visto apenas ter um Delay(3000) para esperar 3s antes de começar o novo jogo. Alguma ideia? O código principal está em baixo (não disponibilizo as classes das naves e afins porque penso não ser preciso).

Obrigado desde já.

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import javax.swing.JApplet;
import javax.swing.JFrame;
import javax.swing.JPanel;

//JApplet SunshineGame
public class SunshineGame extends JApplet
{
Toolkit toolkit = Toolkit.getDefaultToolkit();
Image imageFileLevel1 = toolkit.getImage("universe.jpg");
Image imageFileLevel2 = toolkit.getImage("cosmos.jpg");
Image imageFileLevel3 = toolkit.getImage("solarSystem.jpg");

public static void main(String[] args)
{
 JFrame frame = new JFrame();
 frame.setTitle("Sunshine Game 2.0 by J Amorim");
 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 JApplet applet = new SunshineGame();
 applet.init();
 frame.getContentPane().add(applet);
 frame.pack();
 frame.setVisible(true);
}

//GamePanel initialization
@Override
public void init()
{
 Image imageLevel1 = imageFileLevel1;
 Image imageLevel2 = imageFileLevel2;
 Image imageLevel3 = imageFileLevel3;

 GamePanel panel = new GamePanel(imageLevel1, imageLevel2, imageLevel3);
 getContentPane().add(panel);
}
}

//Class GamePanel
class GamePanel extends JPanel implements Runnable, KeyListener
{
Image image1;
Image image2;
Image image3;

//Planet mars
float MARS_CENTER_X = 118.9f;
float MARS_CENTER_Y = 148.7f;
float marsSpeed = 1.06f;
float marsTetaAngle = 0;

//Planet mercury
float MERCURY_CENTER_X = 89.1f;
float MERCURY_CENTER_Y = 110.5f;
float mercurySpeed = 1.72f;
float mercuryTetaAngle = 0;

//Sun
int SUN_CENTER_X = 30;
int SUN_CENTER_Y = 5;
int sunSize = 50;
int colorDecrease = 300;

//Missile
int missilePosX = -608; //Missile x movement which will increase with missile speed
int MISSILE_POS_Y = 0;
int MISSILE_SPEED_X = 0; //Missile speed (in the beginning the missile is staled)

//Other game pieces
int CANNON_EDGE_X = -616;
int CANNON_EDGE_Y = -5;
int gamePoints = 0;
int nrHitsActual = 0; //Number of times the sun has been hitted
int previousHit = 0; //Previous hit on the sun
int progressBarWidth;
boolean winner = false; //Player wins
boolean lost = false; //Player loses
boolean starting = true; //Player is starting game

//Starship1 starting position
float SS1_X = -395;
float ss1Y = -120;

//Starship1 starting width and height
float SS1_W = 14f;
float ss1H = 8f;

//Starship1 starting speed
float ss1Speed = 2.21f;

//Starship1 starting movement (to set the same ship speed aceleration when up or down)
boolean ss1Up = false;

//Starship2 starting position
float SS2_X = -320;
float ss2Y = -100;

//Starship2 starting width and height
float SS2_W = 14;
float SS2_H = 8;

//Starship2 starting speed
float ss2Speed = 2.84f;

//MotherShip starting position
float MS_X = -260;
float msY = 70;

//MotherShip starting width and height
float MS_W = 14;
float MS_H = 8;

//MotherShip starting speed
float msSpeed = 2.94f;

Ellipse2D elliEarth = new Ellipse2D.Double(-1220, -330, 660, 660);

Rectangle rectMissile = new Rectangle(missilePosX, MISSILE_POS_Y, 80, 10);
Rectangle rectCannon = new Rectangle(CANNON_EDGE_X, CANNON_EDGE_Y, 80, 20);

Ellipse2D elliSun = new Ellipse2D.Double(SUN_CENTER_X - (sunSize / 2), SUN_CENTER_Y - (sunSize / 2), sunSize, sunSize);

Ellipse2D elliMars = new Ellipse2D.Double(MARS_CENTER_X, MARS_CENTER_Y, 20, 20);
Ellipse2D elliMercury = new Ellipse2D.Double(MERCURY_CENTER_X, MERCURY_CENTER_Y, 15, 15);

Rectangle rectProgress = new Rectangle(880, 570, 14, 22);

StarShip smallShip1 = new StarShip(SS1_X, ss1Y, SS1_W, ss1H, 3.0f, 0.4f, 0.0f, 0.0f);
StarShip smallShip2 = new StarShip(SS2_X, ss2Y, SS1_W, ss1H, 3.0f, 0.4f, 5.0f, 0.0f);
StarShip motherShip = new StarShip(MS_X, msY, MS_W, MS_H, 3.0f, 0.4f, 5.0f, -0.8f);

//Class GamePanel constructor
public GamePanel(Image image1, Image image2, Image image3)
{
 this.image1 = image1;
 this.image2 = image2;
 this.image3 = image3;

 setPreferredSize(new Dimension(1100, 600));
 setBackground(Color.BLACK);

 this.setFocusable(true); //Allow panel focus
 addKeyListener(this); //Keyboard events listener

 //Create and initialize the animation thread
 Thread thread = new Thread(this);
 thread.start();
}

@Override
public void paintComponent(Graphics g)
{
 super.paintComponent(g);
 Graphics2D g2 = (Graphics2D)g;

 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

 GradientPaint gradient1 = new GradientPaint(0, 0, new Color(0, 100, 0), 160, 160, new Color(0, 255, 0), true); //Color gradient from green to green at their starting positions
 GradientPaint gradient2 = new GradientPaint(0, 0, new Color(255, 255, 255), 160, 160, new Color(255, 200, 0), true); //Color gradient from white to fading yellow at their starting positions
 Stroke stroke = new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
 Font font1 = new Font("TimesRoman", Font.ROMAN_BASELINE, 28);
 Font font2 = new Font("Verdana", Font.TRUETYPE_FONT, 70);
 Font font3 = new Font("TimesRoman", Font.TRUETYPE_FONT, 40);

 //Draw background images
 if (nrHitsActual <= 4)
 {
	 g2.drawImage(image1, 0, 0, this);
 }
 else if (nrHitsActual >= 5 && nrHitsActual <= 7)
 {
	 g2.drawImage(image2, 0, 0, this);
 }
 else
 {
	 g2.drawImage(image3, 0, 0, this);
 }

 //Wireframe bar drawing
 drawWireFrameBar(g2);

 //Progress bar color growing from green to yellow
 double R = progressBarWidth * 1.64;

 //Fill progress bar drawing
 if (nrHitsActual != previousHit - 1)
 {
	 g2.setColor(new Color((int)R, 175, 0));
	 rectProgress.setFrame(880, 570, progressBarWidth , 23);
	 g2.fill(rectProgress);
	 previousHit = nrHitsActual;
 }

 //Screen text displayed to show points and progress
 setFont(font1);
 g2.setColor(new Color(0, 255, 0));
 g2.drawString("Score: ", 540, 588);
 g2.drawString("Progress: ", 770, 588);
 g2.setColor(Color.YELLOW);
 g2.drawString(" " + gamePoints, 610, 590);

 //Set scale to original values
 g2.scale(1.0, 1.0);

 //****Translation to the center of the sun (to make planets orbit go around it)****
 g2.translate(830, 300);

 double G = colorDecrease * 0.85; //The sun's green color factor will decrease as its size increases

 if (G >= 10) //Avoid green color factor overflow below 0
 {
	 g2.setColor(new Color(255, (int)G, 0)); //Red of the sun increases as its size increases
 }
 else
 {
	 G = 0;
	 g2.setColor(new Color(255, (int)G, 0)); //Red of the sun stays constant at its maximum value
 }

 g2.fill(elliSun);

 g2.setColor(Color.RED);
 g2.fill(rectMissile.getBounds2D());

 g2.setColor(new Color(150, 150, 150));
 g2.fill(rectCannon);

 g2.setColor(new Color(0, 100, 200));
 g2.fill(elliEarth);

 g2.setColor(new Color(50, 150, 250));
 g2.fill(smallShip1);

 //After 5 hits on the sun, draw the 2nd starship
 if (nrHitsActual >= 5)
 {
	 g2.setColor(new Color(250, 50, 100));
	 g2.fill(smallShip2);
 }

 //After 8 hits on the sun, draw the mothership
 if (nrHitsActual >= 8)
 {
	 g2.setColor(new Color(100, 230, 20));
	 g2.fill(motherShip);
 }

	 //Continent geometric transformations and drawing
 AffineTransform continentTx = new AffineTransform();

 SouthAmerica sa = new SouthAmerica(-840, 320);
 g2.translate(165, 0);
 continentTx.rotate(Math.PI / 8.5); //21 degrees rotation (divide 180 by 8.5)
 g2.scale(0.9, 0.9);
 Shape shape1 = continentTx.createTransformedShape(sa);
 g2.setPaint(gradient1);
 g2.setStroke(stroke);
 g2.fill(shape1);
 g2.translate(-165, 0);

 NorthAmerica na = new NorthAmerica(-776, -30);
 g2.translate(33, 35);
 g2.fill(na);
 g2.translate(-33, -35);

 Antarctic an = new Antarctic(-850, 510);
 g2.translate(100, 30);
 continentTx.setToRotation(Math.PI / 8.5); //21 degrees rotation (divide 180 by 8.5)
 g2.scale(0.9, 0.9);
 Shape shape3 = continentTx.createTransformedShape(an);
 g2.setPaint(gradient2);
 g2.fill(shape3);
 g2.translate(-100, -30);

 Arctic ar = new Arctic(-1010, -354);
 g2.translate(80, 150);
 g2.fill(ar);
 g2.translate(-80, -150);

 //Rise scale 0.4
 g2.scale(1.4, 1.4);

 //Planet geometric transformations and drawing
 AffineTransform planetTx = new AffineTransform();

 planetTx.rotate(marsTetaAngle / 90);
 Shape marsShape = planetTx.createTransformedShape(elliMars);
 g2.setColor(new Color(150, 0, 100));
 g2.fill(marsShape);

 planetTx.setToRotation(mercuryTetaAngle / 60);
 Shape mercuryShape = planetTx.createTransformedShape(elliMercury);
 g2.setColor(new Color(100, 150, 0));
 g2.fill(mercuryShape);

 if (mercuryShape.intersects(rectMissile)|| marsShape.intersects(rectMissile))
 {
	 lost = true;
 }

 //****Translation to the coordinates system origin****
 g2.translate(-830, -300);

 //Screen text displayed if player lost the game. Try again?
 if (lost == true)
 {
	 g2.setColor(new Color(255, 0, 0));
	 g2.setFont(font2);
	 g2.drawString(gamePoints + " " + "Points!", 370, 250);
	 g2.setFont(font3);
	 g2.setColor(new Color(0, 255, 0));
	 g2.drawString("Try again?", 460, 385);
	 g2.setFont(font1);
	 g2.setColor(new Color(255, 250, 0));
	 g2.drawString("(Y)", 500, 435);
	 g2.setColor(new Color(255, 0, 250));
	 g2.drawString("(N)", 550, 435);
 }

 //Screen text displayed if player wins the game. Restart?
 if (winner == true)
 {
	 g2.setFont(font2);
	 g2.setColor(new Color(0, 255, 0));
	 g2.drawString("Ah yes, Victory!", 310, 260);
	 g2.setColor(new Color(255, 215, 0));
	 g2.drawString(gamePoints + " " + "Points!", 400, 410);
	 g2.setFont(font1);
	 g2.setColor(new Color(0, 255, 0));
	 g2.drawString("Restart?", 544, 455);
	 g2.setColor(new Color(255, 250, 0));
	 g2.drawString("(Y)", 540, 500);
	 g2.setColor(new Color(255, 0, 250));
	 g2.drawString("(N)", 590, 500);
 }

 //Screen text displayed if player restarts the game
 if (starting == true)
 {
	 g2.setFont(font2);
	 g2.setColor(new Color(0, 255, 0));
	 g2.drawString("Get ready!!", 370, 330);
 }
}

//Running thread function
public void run()
{
 while (true)
 {
	 //After losing or winning, the system waits for the player to either press "Y" or "N" to either restart or exit the current game
	 if (lost == true || winner == true)
	 {
		 do
		 {
			 if (starting == true)
			 {
				 break;
			 }
		 }
		 while (starting == false);
	 }

	 //3 seconds delay to display the text "Get Ready", if player is starting (or restarting) the game
	 if (starting == true || winner == true)
	 {
		 delay(3000);

		 starting = false;
	 }

	 updateStarShip1();

	 if (nrHitsActual >= 5)
	 {
		 updateStarShip2();
	 }

	 if (nrHitsActual >= 8)
	 {
		 updateMotherShip();
	 }

	 missileSunInteraction();
	 updateMars();
	 updateMercury();

	 repaint();

	 try
	 {
		 Thread.sleep(18);
	 } catch (InterruptedException ex)
	 {
		 break;
	 }
 }
}

//Delay function
public void delay(int milliseconds)
{
 try
 {
	 Thread.sleep(milliseconds);
 } catch (Exception e)
 {
 }
}

//Key events

public void keyPressed(KeyEvent e)
{
 //Fire missile
 if (e.getKeyCode() == KeyEvent.VK_SPACE)
 {
	 MISSILE_SPEED_X = 7; //Missile constant speed
 }

 //Restart game
 if (e.getKeyCode() == KeyEvent.VK_Y)
 {
	 starting = true;
	 lost = false;
	 winner = false;

	 resetMissile();
	 resetSun();
	 resetShips();
	 resetPlanets();
	 resetOtherGameVariables();
 }

 //Quit game
 if (e.getKeyCode() == KeyEvent.VK_N || e.getKeyCode() == KeyEvent.VK_Q)
 {
	 System.exit(0);
 }
}

public void keyTyped(KeyEvent e)
{

}

public void keyReleased(KeyEvent e)
{

}

public void missileSunInteraction()
{
 missilePosX = missilePosX + MISSILE_SPEED_X; //Increases missile x position with constant speed
 rectMissile.setLocation(missilePosX, MISSILE_POS_Y); //Refreshes the new missile position

 //Missile hits the sun
 if (elliSun.intersects(rectMissile))
 {
	 nrHitsActual = nrHitsActual + 1; //Increases the number of actual hits on the sun
	 sunSize = sunSize + 20; //Increases sun size
	 colorDecrease = colorDecrease - 28; //Decrease sun's color as it gets bigger

	 missilePosX = -608;
	 MISSILE_SPEED_X = 0;

	 elliSun.setFrame(SUN_CENTER_X - (sunSize / 2), SUN_CENTER_Y - (sunSize / 2), sunSize, sunSize);
	 rectMissile.setLocation(missilePosX, MISSILE_POS_Y);
	 marsSpeed = marsSpeed + 0.29f; //Increases planet mars speed
	 mercurySpeed = mercurySpeed + 0.34f; //Increases planet mercury speed

	 //Acelerate starship1 when its direccion goes up
	 if (ss1Up == true)
	 {
		 ss1Speed = ss1Speed - 0.48f; //Increases starship1 speed
		 ss1H = ss1H + 0.39f; //Increases starship1 height
	 }
	 //Acelerate starship1 when its direccion goes down
	 else
	 {
		 ss1Speed = ss1Speed + 0.48f; //Increases starship1 speed
		 ss1H = ss1H + 0.39f; //Increases starship1 height
	 }

	 //Increases or decreases starship2 speed only when it appears on the screen (after 5 hits on the sun)
	 if (nrHitsActual >= 5)
	 {
		 ss2Speed = ss2Speed + 0.27f; //Increases (on its way down) or decreases (on its way up) starship2 speed
		 gamePoints = gamePoints + 7; // 7 bonus points
	 }

	 //Increases or decreases mothership speed only when it appears on the screen (after 9 hits on the sun)
	 if (nrHitsActual >= 8)
	 {
		 msSpeed = msSpeed + 0.95f; //Increases (on its way down) or decreases (on its way up) mothership speed
		 gamePoints = gamePoints + 10; //10 bonus points
	 }

	 gamePoints = gamePoints + 5; //Increases player score
	 progressBarWidth = nrHitsActual * 14; //Increases progress bar width

	 //Reset everything after victory (11 hits on the sun)
	 if (nrHitsActual == 11)
	 {
		 gamePoints = gamePoints + 25; //25 bonus points
		 winner = true;
	 }
 }
}

public void updateMars()
{
 marsTetaAngle = marsTetaAngle + marsSpeed;
}

public void updateMercury()
{
 mercuryTetaAngle = mercuryTetaAngle + mercurySpeed;
}

public void updateStarShip1()
{
 if (smallShip1.intersects(rectMissile)) //Reset the game after missile hits starship1
 {
	 lost = true;
 }

 ss1Y = ss1Y + ss1Speed ;
 smallShip1.setFrame1(SS1_X, ss1Y , SS1_W, ss1H, 3.0f, 0.4f);

 //Lower wall
 if (ss1Y + 50 > 300)
 {
	 ss1Speed = ss1Speed * (-1);
	 ss1Up = true;
 }

 //Upper wall
 if (ss1Y - 5 < -300)
 {
	 ss1Speed = ss1Speed * (-1);
	 ss1Up = false;
 }
}

public void updateStarShip2()
{
 if (smallShip2.intersects(rectMissile)) //Reset the game after missile hits starship2
 {
	 lost = true;
 }

 ss2Y = ss2Y + ss2Speed;
 smallShip2.setFrame2(SS2_X, ss2Y , SS2_W, SS2_H, 3.0f, 0.4f, 5.0f);

 //Lower wall
 if (ss2Y + 40 > 300)
 {
	 ss2Speed = ss2Speed * (-1);
 }

 //Upper wall
 if (ss2Y - 5 < -300)
 {
	 ss2Speed = ss2Speed * (-1);
 }
}

public void updateMotherShip()
{
 if (motherShip.intersects(rectMissile)) //Reset the game after missile hits mothership
 {
	 lost = true;
 }

 msY = msY - msSpeed;
 motherShip.setFrame3(MS_X, msY, MS_W, MS_H, 3.0f, 0.4f, 5.0f, -0.8f);

 //Lower wall
 if (msY + 55 > 300)
 {
	 msSpeed = msSpeed * (-1);
 }

 //Upper wall
 if (msY - 40 < -300)
 {
	 msSpeed = msSpeed * (-1);
 }
}

public void drawWireFrameBar(Graphics g)
{
 Graphics2D g2 = (Graphics2D)g;

 int rectProgressPosX = 880;

 //First 8 wireframe bar objects growing from darker to brighter green
 double G2 = 175.0d;

 //Last 9 to 11 wireframe bar objects growing from brighter green to mid yellow
 double R = 200.0d;

 for (int i = 0; i < 11; i++)
 {
	 if (i == 0 || i == 1 || i == 2 || i == 3)
	 {
		 g2.setColor(new Color(0, (int)G2, 0));
		 G2 = G2 + 10.5d;
	 }

	 if (i == 4 || i == 5 || i == 6 || i == 7)
	 {
		 g2.setColor(new Color(150, (int)G2, 0));
		 G2 = G2 + 7.5d;
	 }

	 if (i == 8 || i == 9 || i == 10)
	 {
		 g2.setColor(new Color((int)R, (int)G2, 0));
		 R = R + 26.8d;
	 }

	 //Wireframe bar drawing
	 rectProgress = new Rectangle(rectProgressPosX, 570, 14, 22);
	 g2.draw(rectProgress);
	 rectProgressPosX = rectProgressPosX + 14;
 }
}

public void resetSun()
{
 sunSize = 50;
 colorDecrease = 300;

 elliSun.setFrame(SUN_CENTER_X - (sunSize / 2), SUN_CENTER_Y - (sunSize / 2), sunSize, sunSize);
}

public void resetPlanets()
{
 marsSpeed = 1.06f;
 mercurySpeed = 1.72f;
 //The planet's initial position ain't set here so that the game don't become too repetitive
}

public void resetShips()
{
 ss1Speed = 2.21f;
 ss1H = 8;
 ss2Speed = 2.84f;
 msSpeed = 2.94f;
 //The ship's initial position ain't set here so that the game don't become too repetitive
}

public void resetMissile()
{
 missilePosX = -608;
 MISSILE_SPEED_X = 0;

 rectMissile.setFrame(missilePosX, MISSILE_POS_Y, 80, 10);
}

public void resetOtherGameVariables()
{
 nrHitsActual = 0;
 previousHit = 0;
 progressBarWidth = 0;
 gamePoints = 0;
}
}
Edited by apocsantos
geshi
Link to comment
Share on other sites

isto é alguma tentativa de queimar um processador ?

			if (lost == true || winner == true)
			 {
					 do
					 {
							 if (starting == true)
							 {
									 break;
							 }
					 }
					 while (starting == false);
			 }

Não percebi HappyHippyHippo. Esse bloco de código está correcto. É exactamente igual ao ciclo while(true) mas nesse caso que referes, uso uma flag para sair.

Todo o código sempre funcionou bem durante anos a fio no meu PC antigo e em pc's da Universidade. Apenas me dá problemas neste novo PC.

Edited by alllright
Link to comment
Share on other sites

Teimar não teimo simplesmente acho estranhíssimo como é possível isto acontecer, por isso vim aqui para tentar encontrar uma solução.

Mas pergunto-te, se fosse da estrutura do código não achas que daria problemas em todo o lado?

Como eu já não mexo neste programa há alguns anos (foi programado em 2010 se não me engano) por isso não sei bem se entretanto terei que mudar a sintaxe de alguma linha ou mesmo a sua estrutura.

Achas que o problema pode ser daquele bloco? (embora tenha funcionado sempre bem?). Podia substituí-lo por algo similar? Aprendi a programar threads desta forma e nunca tive problemas, mas pode haver outras formas que eu desconheça, não sei. É que já dei voltas e voltas e não me ocorre nada, infelizmente.

Obrigado na mesma. 😉

Link to comment
Share on other sites

Mas pergunto-te, se fosse da estrutura do código não achas que daria problemas em todo o lado?

não quando o problema é de concorrência.

já ouviste falar de resource starving ?

o problema deverá ficar resolvido bastando por um delay dentro do cíclo que referênciei.

no que toca à estrutura do código, sim, está muito ... iniciante

IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

Obrigado HappyHippyHippo.

Realmente o delay resolveu-me o problema no pc novo. Já tinha ouvido falar de resource starvation, sim, especialmente no que diz respeito à prioridade na execução de processos no CPU. Mas neste caso nunca imaginei que fosse este o caso, pois como te disse, no P4 funciona direitinho. Mas como pode um Pentium 4 alocar os recursos necessários, neste caso, e um I7 não? É que se for este o caso, é um daqueles problemas em que só mesmo um expert se vai lembrar.

Já no caso da estrutura, referes-te a todo o código ou apenas a esse bloco? Eu tento sempre identar tudo correctamente e colocar os respectivos comentários para saber do que trata cada pedaço. Este programa já não é assim tão básico no meu entender e acho que já requer alguma ginástica de programação (pois já fiz alguns bem bem mais simples) embora também já tenha feito programas com cerca de 6,000 linhas e em que tudo parece confuso.

Mas estou sempre aberto a sugestões para poder melhorar. 👍 Obrigado mais uma vez.

Edited by alllright
Link to comment
Share on other sites

😁 ya, se pressionar qualquer uma das teclas, o jogo ou reinicia ou sai.

De salientar que fiz este projecto há uns anos atrás para uma cadeira de Computação Gráfica e isto ficou (bastante) inacabado. Ficou praticamente um protótipo de apenas um nível em fase experimental.

Peguei-lhe agora para ver se consigo acabar isto e fazer um joguito "de jeito" mas realmente ainda me falta muito trabalho (som, um menu, níveis, etc).

Mas a situação antes de usar o delay que indicáste ficou-me aqui atravessada. Continuo sem saber porque é que não saiu?! do ciclo de controlo (o break deveria funcionar, pois a flag passa a true).

E realmente parece que saiu, pois o código bloqueava no "Get Ready", após o "Y" (isto para não falar de ser apenas neste pc, como te disse antes).

Ou então volta lá não sei, pois nem mesmo com debug consigo perceber isso.

Atenção que não estou a ser picuinhas e já vi que percebes disto. Eu é que também gosto de saber o porquê das coisas.

Weird things can happen..

Link to comment
Share on other sites

  • Solution

a tua aplicação corre em dois threads:

- Main Thread que gere a janela e os eventos que esta recebe do sistema operativo. é esta thread the executa as chamadas das funções relacionadas com o keylistener

- o Runnable the chamas no início da aplicação que será responsável pela actualização do mundo assim apresentar-lo na janela

quando tens o ciclo infinito do "Runnable" à espera da mudança do valor existente na variável starting, não estás a libertar o processador para que este processe os eventos no Main Thread. No final, o que acontece é o que é chamado de resource starving no MainThread.

o que te disse para fazeres é colocares um delay dentro do ciclo (pode não parecer, mas a quantidade de vezes que o ciclo iria correr em 10 milisegundos é enorme, for por isso que perguntei se estavas a ver se querias queimar o processador). Ao colocar o delay, estás a libertar o processador para que os eventos possam ser processados.

no que toca a debugging de problemas de multithreading, raramente um debug te ajudará.

ou sabes o que fazes, ou as dores de cabeça são enormes.

IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

Grande explicação obrigado. 🙂

Eu sabia que o delay libertava recursos para que os processos pudessem ser executados no CPU (aliás o meu Prof na altura alertou-me para esse facto) mas o que eu achei estranho foi isso nunca ter acontecido no meu velho P4 (que foi o PC onde programei este projecto). Este foi, na altura, o meu primeiro contacto com conceitos de herança e interface e por isso mesmo fui alertado para os comportamentos a ter em atenção precisamente nas classes Runnable (implementa o método run, entre outros) e KeyListener (implementa os vários métodos para as teclas).

Imagina qual foi o meu espanto quando o executei neste novo PC e bloqueou. Como já não pegava no projecto há muito tempo lembrei-me logo que podia ter ocorrido alguma alteração no código feita inadvertidamente ou que fosse um problema das versões do Java serem diferentes em ambos os PC's. Fui logo testar o projecto no PC "original" e continou (e continua) a não dar problemas de bloqueios (funciona bem sem o delay), por isso é que descartei essa hipótese, logo á partida.

Mas depois disso ainda fiz outro teste antes de vir aqui. Executei o projecto em ambos os pc's ao mesmo tempo e comparei resultados de carga no CPU e/ou RAM. No meu velhinho P4 a carga do CPU durante a execução do jogo era alta (acima dos 80%) também porque este CPU já tem cerca de 15 anos e deverá estar em fim de vida. Mas nunca bloqueou.

Já no PC novo a carga no CPU (QuadCore de 4ª geração) foi sempre de cerca de 38% (quer durante a execução, quer durante o bloqueio). Ou seja, não havia indícios de consumo excessivo de recursos, mesmo no bloqueio, e por isso fiquei mesmo sem saída.

Como já reparei que não te referes especificamente ao facto de o projecto funcionar no meu PC velho, deduzo que também estejas como eu (por que raio isto acontece).

Mas a tua explicação faz todo o sentido e tem lógica que assim seja. 👍

Link to comment
Share on other sites

Já no PC novo a carga no CPU (QuadCore de 4ª geração) foi sempre de cerca de 38% (quer durante a execução, quer durante o bloqueio). Ou seja, não havia indícios de consumo excessivo de recursos, mesmo no bloqueio, e por isso fiquei mesmo sem saída.

errado.

estás a ver a carga total dos 4 cores. deverias ver individual e um deles deverá estar a bater nos 100% (25% do processador)

Como já reparei que não te referes especificamente ao facto de o projecto funcionar no meu PC velho, deduzo que também estejas como eu (por que raio isto acontece).

não porque tem haver com o escalonamento por parte do SO.

se o teu processador antigo era single core, o SO tenta de alguma forma "enfiar" tempo para todos os threads (não só da mesma aplicação) estando sempre a saltar de contexto.

como o SO agora sabe que tens 4 cores, reservou um core para a aplicação e esqueceu o assunto porque tens os restantes 3 para o que necessita (o SO).

  • Vote 1
IRC : sim, é algo que ainda existe >> #p@p
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.