This is my applet code for a moving banner .It is working properly but there is one doubt .
import java.applet.*;
import java.awt.*;
/*<html>
<applet code ="SimpleBanner" width="2000" height="2000"></applet></html>*/
public class SimpleBanner extends Applet implements Runnable{
String msg=" A Simple Banner Is Moving";
boolean flag=false;
Font f=new Font("TimesRoman",Font.BOLD,50);
int i=10;
public void init()
{
setBackground(Color.gray);
setFont(f);
setForeground(Color.green);
}
public void start()
{
Thread t=new Thread(this);
t.start();
}
public void run()
{
for(;;)
{
try{
repaint();
if(flag)
break;
Thread.sleep(250);
}catch(InterruptedException e){}
}
}
public void paint(Graphics g)
{
char ch=msg.charAt(0);
msg=msg.substring(1,msg.length());
msg+=ch;
drawString(msg,300,100);
}
public void stop()
{
flag=true;
}
}
As you can see I am not extending Graphics class and I am using setFont() method defined in Graphics class without its object how this is possible? And if I try to call drawString() method in paint() method without g it is not working.
Related
I know the basic concepts of OOP, I am trying my hands on Android programming.(Games in particular). I am trying to implement a game project from this book Android Game programming by example. I am able to understand theoretically what is being said. But when I put together the pieces of code, into a single java class TDView.java file, I get an error in Android studio. Maybe I misunderstood some phrase and Put a piece where I wasn't suppose to put it.
The errors are labeled error1 and error2 in the code below:
package com.gamecodeschool.c1tappydefender;
import android.content.Context;
import android.view.SurfaceView;
public class TDView extends SurfaceView implements Runnable {
volatile boolean playing;
Thread gameThread = null;
#Override
public void run() {
while (playing) {
update();
draw();
control();
} //error2: it says a semicolon is needed here.
private void update(){
}
private void draw(){
}
private void control(){
}
}// error1: it says class or interface missing
public TDView(Context context) {
super(context);
}
// Clean up our thread if the game is interrupted or the player quits
public void pause() {
playing = false;
try {
gameThread.join();
} catch (InterruptedException e) {
}
}
// Make a new thread and start it
// Execution moves to our R
public void resume() {
playing = true;
gameThread = new Thread(this);
gameThread.start();
}
}
Move your method declaration outside of the declaration of your run method. this should do the trick
public void run() {
while (playing) {
update();
draw();
control();
}
}
private void update(){
}
private void draw(){
}
private void control(){
}
I'm actually coding pacman for a project, but I've encountered an issue, when I've added this part :
#Override
public void keyPressed(KeyEvent e){
dir=e.getKeyCode();
}
The program doesn't call that specific method that I need in order to get the right direction and then put it in the update one.
Here is the full code which I'm still working on :
import java.awt.Graphics;
import org.game.engine.Game;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.game.engine.GameApplication;
public class Pacman extends Game {
BufferedImage pacman;
int frame;
int dir;
int x,y;
final int STEP=2;
public static void main (String[] args){
GameApplication.start(new Pacman());
}
public Pacman(){
title="Pacman";
width=height=500;
dir=KeyEvent.VK_RIGHT;
x=300;
y=200;
try {
pacman = ImageIO.read(new File("pacman.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
public void keyPressed(KeyEvent e){
dir=e.getKeyCode();
}
#Override
public void update() {
frame++;
if(frame>2){
frame=0;
}
**switch(dir){
case KeyEvent.VK_LEFT:
x-=STEP;
break;
case KeyEvent.VK_RIGHT:
x+=STEP;
break;**
}
if(x<0){
x=0;
}
else if(x> width -28-15){
x= width-28-15;
}
}
#Override
public void draw(Graphics g) {
g.drawImage(pacman.getSubimage(frame*30,0,28,28),x,y,null);
}
#Override
public void init() {
}
}
EXTRA Details :
So basically in order to run the project I've a game engine that helps me to process the shape of the game.
In order to do that I have 4 classes :
1/ Game Application :
package org.game.engine;
import javax.swing.JFrame;
public class GameApplication {
static public void start (Game jeu) {
JFrame fenetre=new JFrame(jeu.getTitle());
fenetre.setSize(jeu.getWidth(),jeu.getHeight());
fenetre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GameCanvas canvas=new GameCanvas(jeu);
fenetre.add(canvas);
fenetre.setVisible(true);
GameLoop loop= new GameLoop(jeu,canvas);
loop.start();
}
}
2/ GameCanvas
package org.game.engine;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JComponent;
public class GameCanvas extends JComponent{
private final Game game;
public GameCanvas(Game game) {
this.game=game;
**addKeyListener(this.game);**
requestFocus();
}
#Override
public void paintComponent(Graphics g){
game.draw(g);
}
}
3/ Game Loop
package org.game.engine;
public class GameLoop extends Thread {
private final Game game;
private final GameCanvas canvas;
public GameLoop(Game game, GameCanvas canvas) {
this.game=game;
this.canvas=canvas;
}
#Override
public void run() {
game.init();
while(!game.isOver()){
game.update();
canvas.repaint();
try {
Thread.sleep(game.getDelay());
} catch (InterruptedException e) {
}
}
}
}
And finally the game itself :
4/ Game
package org.game.engine;
import java.awt.Graphics;
**import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;**
public abstract class Game **implements KeyListener**{
protected boolean over;
protected int delay=50;
protected int width=500;
protected int height=500;
protected String title="Mon jeu";
abstract public void update();
abstract public void draw(Graphics g);
abstract public void init();
public int getWidth(){ return width;}
public int getHeight(){return height;}
public String getTitle(){return title;}
public boolean isOver(){ return over;}
public long getDelay(){ return delay;}
**public void keyTyped(KeyEvent e){}
public void keyPressed(KeyEvent e){}
public void keyReleased(KeyEvent e){}**
}
The 1/ Game Application is for the execution part of the process (layout display etc..)
The 2/ Game Canvas is there in order to draw the content of the window, besides it also calls the Keylistener by : addKeyListener(this.game);
The 3/ Game Loop contains the main loop of the programm in the run method
And finally the 4/ Game contains all the basic parametres of the programm such as the title the size and it also implements the Keylisteners.
For key press to be handled correctly you need to do following:
Register the key listener/ key adapter to Swing (or AWT).
After key pressed event is called call the method that should respond to the key.
May be you are doing these right. If so you need to narrow down the problem further for getting reasonable help.
You're storing the key value in a and then checking dir in your switch. Obviously this will not work. You do not seem to use a anywhere else in the application so I suggest you remove the variable completely to avoid confusion.
This small applet is supposed to move a String from the bottom to the top of applet frame, when it reaches top it should start from the bottom again. Problem is it's only moving when I resize the applet window. It doesn't move itself, why does it works that way?
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
public class Zad1 extends Applet implements Runnable {
Thread runner;
int yPos = 500;
public void start() {
if (runner == null) {
runner = new Thread(this);
}
}
public void stop() {
if (runner != null) {
runner = null;
}
}
public void run() {
while (true) {
repaint();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void paint(Graphics g) {
g.drawString("Hello java", 50, yPos);
yPos--;
if (yPos < -30)
yPos = 500;
}
}
The thread is not started
runner = new Thread(this);
runner.start(); // <----------- Insert this!
But note that the style of this applet is bad in many ways (e.g. there should be no logic in "paint", you should probably not overwrite "paint" of an Applet at all, you should consider a JApplet, etc...). You should probably read http://docs.oracle.com/javase/tutorial/uiswing/components/applet.html and other examples.
import java.applet.*;
import java.awt.*;
public class rectangle extends Applet
{
void slp(int x)
{
try
{
Thread.sleep(x);
}
catch(Exception e)
{}
}
public void init()
{}
public void paint(Graphics g)
{
for(int i=0;i<10;i++)
{
rectangle rect=new rectangle();
g.drawRect(20+i,40+i,40,50);
slp(10);
rect.repaint();
}
}
}
You are blocking the AWT Event Dispatch Thread (EDT). Use javax.swing.Timer (note the Swing one) instead of the for loop.
(Also #Override is useful, and sticking to the normal Java coding conventions.)
I'm making my first Applet. I have a JPanel which creates a Swing GUI and performs CPU intensive tasks (repainting a Component 60Hz). My Applet displays this JPanel on event dispatching thread. here is an abstraction of the problem. Normally I would launch the applet from an html document instead of having a main method. This program puts about a 40% load on my CPU.
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
public class TestApplet extends JApplet {
TestPanel tp;
public void init() {
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
createGUI();
}
});
} catch (Exception e) {
System.err.println("createGUI didn't complete successfully");
}
}
private void createGUI() {
//Create and set up the content pane.
tp = new TestPanel();
tp.setOpaque(true);
setContentPane(tp);
}
public static void main(String[] args) {
JFrame f = new JFrame("Fish Tank");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JApplet ap = new TestApplet();
ap.init();
f.add("Center", ap);
f.pack();
f.setVisible(true);
}
}
class TestPanel extends JPanel{
public TestTank tt = new TestTank();
public TestPanel() {add(tt);}
public void stop() {tt.stop();}
public void start() {tt.start();}
}
class TestTank extends Component implements ActionListener{
private javax.swing.Timer timer;
TestTank(){
timer = new javax.swing.Timer(17, this);
timer.setCoalesce(true);
timer.start();
}
public Dimension getPreferredSize(){
return new Dimension(900, 700);
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Dimension size = getSize();
g2.setPaint(new GradientPaint(0,0,Color.RED,900, 0,Color.WHITE));
g2.fill(new Rectangle2D.Float(0,0,size.width,size.height));
}
public void actionPerformed(ActionEvent e) {
repaint();
}
public void stop(){timer.stop();}
public void start(){timer.start();}
}
My question: How do I suspend and resume execution of the JPanel (FishTankPanel) when the user switches tabs or minimizes the browser? I want the Applet to stop using the CPU when the user can't see what it is doing. I need to capture browser events in order to execute tp.stop() in the applet. I have tried to execute them with window event listeners in the JPanel, and by overriding the start() and stop() methods in the Applet. I have been unsuccessful. Any suggestions or solutions would be appreciated.
I would do as Dave said and use the JApplet override start and stop methods to call your GUI methods. For instance, see changes in code:
public class TestApplet extends JApplet {
TestPanel tp;
public void init() {
// ... no change
}
private void createGUI() {
// ... no change
}
#Override
public void stop() {
if (tp != null) {
tp.stop();
}
}
#Override
public void start() {
if (tp != null) {
tp.start();
}
}
}
class TestTank extends Component implements ActionListener {
private javax.swing.Timer timer;
// ... no change
public void stop() {
timer.stop();
System.out.println("stop");
}
public void start() {
timer.start();
System.out.println("start");
}
}
It seems you might need to leverage some JS for this. E.G. use the JS shown in this answer to explicitly call the applet start() & stop() methods on focus & blur detection respectively.
The solution for my problem was to use javascript to implement the Page Visibility API. I then called the appropriate Java methods from within the javascript script.