Achievement display
Production ideas
Step 1: Discover the class (object)
人物-小丑: Buffoon
子弹-帽子:Missile
墙体:Wall
爆炸物:Explode
Step 2: Discover the attributes
小丑:宽和高,位置(x,y),移动速度
帽子:宽和高,位置(x,y),移动速度
墙体:宽和高,位置(x,y)
爆炸物:宽和高,位置(x,y)
Step 3: Discover the method
小丑:移动、攻击、人物撞边界
子弹:移动、子弹撞墙、子弹撞边界
爆炸物:消失
Difficulty analysis
How to create the form
public class GameClient extends Frame
Implement Java form by inheriting Frame class
public class Frame extends Window implements MenuContainer
The Frame class inherits the Window class and MenuContainer interface
How to load pictures into the form
Step 1: Create CommonUtils, a commonly used tool class, and create a new getImage method to convert image resources into Java objects
public class CommonUtils {
/**
* 读取图片资源, 转变为Java对象 Image
* @param imgPath 图片路径
* @return Image对象
*/
public static Image getImage(String imgPath) {
ImageIcon imageIcon = new ImageIcon(imgPath);
return imageIcon.getImage();
}
}
Step 2: Call the getImage method to add the object image
public class GameClient extends Frame {
Image bg_image = CommonUtils.getImage("images/bg.png");
Image explode = CommonUtils.getImage("images/explode.png");
Image missile = CommonUtils.getImage("images/missile.png");
Image wall_h = CommonUtils.getImage("images/wall-h.png");
Image wall_v = CommonUtils.getImage("images/wall-v.png");
Image buffoon = CommonUtils.getImage("images/body/s-left.png");
Step 3: Rewrite the paint method of Framed to implement the form to load pictures
@Override
public void paint(Graphics g){
//画背景图
g.drawImage(bg_image,0,0,1100,700,this);
//画小丑
g.drawImage(buffoon,300,200,80,80,this);
//画爆炸物
g.drawImage(explode,800,400,90,90,this);
//画原谅帽
g.drawImage(missile,300,300,60,60,this);
//画横着的墙体
g.drawImage(wall_h,400,300,100,20,this);
//画竖着的墙体
g.drawImage(wall_v,400,300,20,100,this);
The drawImage method of the Graphics class needs to provide the Image class parameter, the x parameter of the form, the y parameter of the form, the width of the Image class, the length of the Image class, and the observer (the object to be notified when more images are converted)
Implementation of object movement
The direction of the target map is usually determined by the rule of "up to north, lower to south, left west and right east". The eight directions of movement usually refer to north, northeast, east, southeast, south, southwest, west, and northwest. Therefore, when defining the moving direction, use up, left, bottom, right, top right, bottom right, top left, and bottom left to indicate
小丑:移动 move<Orientation类传递方向参数>
'left向左' :x = x - this.speed;
'right向右' :x = x + this.speed;
'down向下' :y = y + this.speed;
'up向上' :y = y - this.speed;
'ur东北方向' : x = x + this.speed;
y = y - this.speed;
'ul西北方向' : x = x - this.speed;
y = y - this.speed;
'dr东南方向' : x = x + this.speed;
y = y + this.speed;
'dl西南方向' : x = x - this.speed;
y = y + this.speed;
The realization of form closing
public void start() {
//窗体添加侦听方法
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
//退出游戏
System.exit(0);
}
});
WindowAdapter class :
1. An abstract adapter class that receives window events. The methods in this class are empty. The purpose of this class is to facilitate the creation of listener objects.
2. Extend this class to create a WindowEvent listener and override the method for the required event. (If you want to implement the WindowListener interface, you must define all methods in the interface. This abstract class defines all methods as null, so you only need to define methods for the events you care about.
3. Use extended classes to create listener objects , And then use the addWindowListener method of the window to register a listener with the window. When the state of the window is changed by opening, closing, activating or deactivating, iconizing or de-iconizing, the relevant method in the listener object will be called , And pass WindowEvent to the method.
windowAdapter listener
The realization of key event trigger
this.addKeyListener(new KeyAdapter() {
//键盘按下的时候出发
@Override
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
}
//键盘松开
@Override
public void keyReleased(KeyEvent e) {
//获取被按下的键对应的数值,如,a:67,b:68
int keyCode = e.getKeyCode();
switch (keyCode){
case KeyEvent.VK_UP:
System.out.println("向上走!!!");
buffoon.setDir("UP");
break;
case KeyEvent.VK_DOWN:
System.out.println("向下走");
buffoon.setDir("DOWN");
break;
case KeyEvent.VK_RIGHT:
System.out.println("向右走");
buffoon.setDir("RIGHT");
break;
case KeyEvent.VK_LEFT:
System.out.println("向左走!!");
buffoon.setDir("LEFT");
break;
}
buffoon.move(buffoon.getDir());
}
});
Key points of keystroke
Point 1:'new KeyAdapter()' Create a new key event listener, and register the listener to the main form through addKeyListener();
Point 2: Rewrite KeyAdapter methods, namely KeyTyped (type), KeyPresdded (press Next), KeyReleased (released). Here we only listen to the KeyPressed event and rewrite this method to realize the change of the character's direction state; the
third point: KeyEvent e.getKeyCode returns the key value corresponding to the key pressed, refer to the key value property of KeyEvent. Java 8 online API
Create object Buffoon.move() method
public void move(String dir){
switch (dir){
case "UP":
this.y -= this.speed;
setDir("STOP");
break;
case "DOWN":
this.y += this.speed;
setDir("STOP");
break;
case "RIGHT":
this.x += this.speed;
setDir("STOP");
break;
case "LEFT":
this.x -= this.speed;
setDir("STOP");
break;
}
Every time a key event is monitored, the move method is called to realize the movement of the buffoon object
Principle of object movement
The moving picture of the object is also called animation. It displays a series of continuous animated pictures frame by frame on the screen, and then displays the next frame at a short interval. This is repeated, using the human eye’s “persistence of vision”. 'The phenomenon subjectively feels as if the objects in the picture are moving.
FPS (Frames Per Second) is the number of frames per second. One frame is a static portrait, and the movie playback speed is 24FPS. The more frames, the smoother the displayed motion. In general, the minimum to avoid jerky movements is 30FPS. FPS Baidu Encyclopedia
Animated moving porter-thread
What is a thread? A
thread is the smallest unit that an operating system can perform operation scheduling. It is included in the process and is the actual operating unit in the process. A thread refers to a single sequential control flow in a process. Multiple threads can be concurrent in a process, and each thread executes different tasks in parallel.
/**
* 定义一个重新绘制画面的线程,相当于招一个工人专门去从事这项工作
*/
public class RePaintThread implements Runnable{
@Override
//线程操作的全都在run方法中
public void run() {
while (true){
//每50毫秒 执行一次
try {
Thread.sleep(20);
//重新绘制图像
gameClient.repaint();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Point 1: Runnable interface
public class RePaintThread implements Runnable
When creating a thread with an object that implements interface Runnable, starting the thread will cause the run method of the object to be called in an independently executing thread.
Point two: Override the Run method
The general contract of the run method is: it may perform any desired action.
Repaint the image
gameClient.repaint();
Key point 3: Thread.sleep—the time interval between repeated execution of the thread 1. Use'While(
true)' to construct an infinite loop
2. Perform repaint() in an infinite loop to repaint the shape method
3. Thread interrupted exception (InterruptedException) is one of the manifestations of the current thread being interrupted. When you encounter this exception, if you don't know how to handle it, you should throw it upward.