码迷,mamicode.com
首页 > 编程语言 > 详细

Java开发冒险(AVG)游戏杂谈

时间:2015-10-11 16:50:07      阅读:366      评论:0      收藏:0      [点我收藏+]

标签:

   之前用过Android,Python的pygame,c#编程语言开发过游戏,一般来说,Java开发的游戏通常是AVG(英文adwenture game的简称)冒险游戏。

就技术角度而言,使用Java AVG 开发可以算得所有游戏类型中最容易的。一款简单 AVG 游戏的制作难度甚至在贪食蛇、俄罗斯方块之下。由于实现的简易性,导致 AVG 的开发重心往往着重于策划及美工,程序员的作用则微乎其微。同时也正因 AVG 开发的门坎约等于 0 ,所以此类型的同人游戏之多即可堪称世界之冠。另外, AVG 开发工具普及的也促进了 AVG 的量产化。利用工具,即始是小说作者、漫画家等非软件专业出身的人士,往往也能轻易制作出顶级的 AVG 大作。(顺便一提,目前我所见过最好的 AVG 制作工具是鬼子的 livemaker ,采用类似思维导图的方式构造整个游戏,很多轻小说作者乃至网络漫画家用它制作自己作品的宣传游戏。但就技术角度上说, livemaker 的开发依旧没什么难度 ......
 
  由于 AVG 的大泛滥,通常仅有文字、图片及语音的 AVG 往往无法满足用户需求( H 除外-_-)。我们每每可在 AVG 游戏类型后发现个 + 号,比如《樱花大战》是 AVG+SLG ,《生化危机》是 AVG+ACT 。所以客观上说, AVG 开发仅仅能进行字图的交互是不够的,还要解决多模块组件的协调问题。
 
  Java 桌面应用开发中 , 我们都知道绘图是极为简单的,有 Image Graphics 两个对象就可以 Paint 一个图形,即使图形对象再多,最后它们也必须统一在一个 Paint 中,所以 Java 中不存在图像的交互问题。
 
但问题在于,图像的显示可以统一,但是触发图像变化的事件却是很难统一的。比如现在有需求如下,在 AVG 模式中,触发键盘事件上、下、左、右时为控制画面的前进、后退,切换模式到 SLG 模 式后,设定上、下、左、右是光标移动,那么如果我要在程序中实现,就必须记录当前模式,而后根据不同模式调用事件,再反馈到图形上。如果只有几个事件的区 别,我们当然可以很容易用分支来实现;问题是,随着游戏规模的加大,这些分支将成几何倍数增多,单纯的分支判定到最后只能忙于应付,落个费力不讨好。
 
其实在这时,我们大可以使用一些技巧来轻松解决问题。
 

 
 
首先,我们构造一个接口,命名为IControl,继承鼠标及键盘监听,并在其中设定两个抽象方法:
 
   
  1. package org.loon.simple.avg;  
  2. import java.awt.Graphics;  
  3. import java.awt.event.KeyListener;  
  4. import java.awt.event.MouseListener;  
  5. import java.awt.event.MouseMotionListener;  
  6. /** 
  7.  * Copyright 2008 - 2009 
  8.  *  
  9.  * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
  10.  * use this file except in compliance with the License. You may obtain a copy of 
  11.  * the License at 
  12.  *  
  13.  * [url]http://www.apache.org/licenses/LICENSE-2.0[/url] 
  14.  *  
  15.  * Unless required by applicable law or agreed to in writing, software 
  16.  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
  17.  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
  18.  * License for the specific language governing permissions and limitations under 
  19.  * the License. 
  20.  *  
  21.  * @project loonframework 
  22.  * @author chenpeng 
  23.  * @email:ceponline@yahoo.com.cn 
  24.  * @version 0.1 
  25.  */  
  26. public interface IControl extends MouseListener, MouseMotionListener,  
  27.         KeyListener {  
  28.     public abstract void draw(final Graphics g);  
  29.     public abstract IControl invoke();  
  30. }  
 
 
  而后,再构造一个接口,命名为IAVG,同样继承鼠标及键盘监听,并在其中设定三个抽象方法,用以操作IControl接口:

   
  1. package org.loon.simple.avg;  
  2. import java.awt.Graphics;  
  3. import java.awt.event.KeyListener;  
  4. import java.awt.event.MouseListener;  
  5. import java.awt.event.MouseMotionListener;  
  6. /** 
  7.  * Copyright 2008 - 2009 
  8.  *  
  9.  * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
  10.  * use this file except in compliance with the License. You may obtain a copy of 
  11.  * the License at 
  12.  *  
  13.  * [url]http://www.apache.org/licenses/LICENSE-2.0[/url] 
  14.  *  
  15.  * Unless required by applicable law or agreed to in writing, software 
  16.  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
  17.  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
  18.  * License for the specific language governing permissions and limitations under 
  19.  * the License. 
  20.  *  
  21.  * @project loonframework 
  22.  * @author chenpeng 
  23.  * @email:ceponline@yahoo.com.cn 
  24.  * @version 0.1 
  25.  */  
  26. public interface IAVG extends MouseListener, MouseMotionListener,  
  27.         KeyListener {  
  28.     public abstract void draw(final Graphics g);  
  29.     public abstract IControl getControl();  
  30.     public abstract void setControl(final IControl control);  
  31. }   


     再后,制作一个显示图像用组件,命名为AVGCanva,继承自Canvas。
 
    
  1. package org.loon.simple.avg;  
  2. import java.awt.Canvas;  
  3. import java.awt.Graphics;  
  4. /** 
  5.  * Copyright 2008 - 2009 
  6.  *  
  7.  * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
  8.  * use this file except in compliance with the License. You may obtain a copy of 
  9.  * the License at 
  10.  *  
  11.  * [url]http://www.apache.org/licenses/LICENSE-2.0[/url] 
  12.  *  
  13.  * Unless required by applicable law or agreed to in writing, software 
  14.  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
  15.  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
  16.  * License for the specific language governing permissions and limitations under 
  17.  * the License. 
  18.  *  
  19.  * @project loonframework 
  20.  * @author chenpeng 
  21.  * @email:ceponline@yahoo.com.cn 
  22.  * @version 0.1 
  23.  */  
  24. public class AVGCanvas extends Canvas {  
  25.     /** 
  26.      *  
  27.      */  
  28.     private static final long serialVersionUID = 1982278682597393958L;  
  29.     private boolean start;  
  30.     private IAVG avg;  
  31.     public AVGCanvas(IAVG handler) {  
  32.         this.avg = handler;  
  33.         this.start = false;  
  34.         this.addKeyListener(handler);  
  35.         this.addMouseListener(handler);  
  36.         this.addMouseMotionListener(handler);  
  37.     }  
  38.       
  39.     public void update(Graphics g) {  
  40.         paint(g);  
  41.     }  
  42.     public void paint(Graphics g) {  
  43.         if (this.start) {  
  44.             this.avg.draw(g);  
  45.         }  
  46.     }  
  47.     public void startPaint() {  
  48.         this.start = true;  
  49.     }  
  50.     public void endPaint() {  
  51.         this.start = false;  
  52.     }  
  53. }  
 
     这段代码中的paint方法中并没有现成的方法,而是调用了IAVG接口的draw。紧接着,我们再设定一个AVGFrame用以加载AVGCanvas。
 
   
  1. package org.loon.simple.avg;  
  2. import java.awt.Color;  
  3. import java.awt.Dimension;  
  4. import java.awt.Frame;  
  5. import java.awt.event.WindowAdapter;  
  6. import java.awt.event.WindowEvent;  
  7.   
  8. /** 
  9.  * Copyright 2008 - 2009 
  10.  *  
  11.  * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
  12.  * use this file except in compliance with the License. You may obtain a copy of 
  13.  * the License at 
  14.  *  
  15.  * [url]http://www.apache.org/licenses/LICENSE-2.0[/url] 
  16.  *  
  17.  * Unless required by applicable law or agreed to in writing, software 
  18.  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
  19.  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
  20.  * License for the specific language governing permissions and limitations under 
  21.  * the License. 
  22.  *  
  23.  * @project loonframework 
  24.  * @author chenpeng 
  25.  * @email:ceponline@yahoo.com.cn 
  26.  * @version 0.1 
  27.  */  
  28. public class AVGFrame extends Frame implements Runnable {  
  29.     /** 
  30.      *  
  31.      */  
  32.     private static final long serialVersionUID = 198284399945549558L;  
  33.     private IAVG avg;  
  34.     private AVGCanvas canvas;  
  35.     private boolean fps;  
  36.     private String titleName;  
  37.     private Thread mainLoop;  
  38.     public AVGFrame(String titleName, int width, int height) {  
  39.         this(new AVG(), titleName, width, height);  
  40.     }  
  41.     public AVGFrame(IAVG avg, String titleName, int width, int height) {  
  42.         super(titleName);  
  43.         Lib.WIDTH = width;  
  44.         Lib.HEIGHT = height;  
  45.         this.avg = avg;  
  46.         this.titleName = titleName;  
  47.         this.addKeyListener(avg);  
  48.         this.setPreferredSize(new Dimension(width + 5, height + 25));  
  49.         this.initCanvas(Lib.WIDTH, Lib.HEIGHT);  
  50.         this.pack();  
  51.         this.addWindowListener(new WindowAdapter() {  
  52.             public void windowClosing(WindowEvent e) {  
  53.                 System.exit(0);  
  54.             }  
  55.         });  
  56.         this.setResizable(false);  
  57.         this.setLocationRelativeTo(null);  
  58.         this.setVisible(true);  
  59.     }  
  60.     public void run() {  
  61.         gameLoop();  
  62.     }  
  63.     /** 
  64.      * 开始循环窗体图像 
  65.      *  
  66.      */  
  67.     private synchronized void gameLoop() {  
  68.         canvas.startPaint();  
  69.         long second = 0L;  
  70.         int moveCount = 0;  
  71.         // 循环绘制  
  72.         for (;;) {  
  73.             long start = System.currentTimeMillis();  
  74.             this.paintScreen();  
  75.             long end = System.currentTimeMillis();  
  76.             long time = end - start;  
  77.             long sleepTime = 20L - time;  
  78.             if (sleepTime < 0L)  
  79.                 sleepTime = 0L;  
  80.             try {  
  81.                 Thread.sleep(sleepTime);  
  82.             } catch (InterruptedException e) {  
  83.                 e.printStackTrace();  
  84.             }  
  85.             if (this.fps) {  
  86.                 moveCount++;  
  87.                 second += System.currentTimeMillis() - start;  
  88.                 if (second >= 1000L) {  
  89.                     this.setTitle(new StringBuilder(titleName).append(" FPS:")  
  90.                             .append(moveCount).toString());  
  91.                     moveCount = 0;  
  92.                     second = 0L;  
  93.                 }  
  94.             }  
  95.         }  
  96.     }  
  97.     /** 
  98.      * 启动游戏循环 
  99.      *  
  100.      */  
  101.     public void mainLoop() {  
  102.         this.mainLoop = new Thread(this);  
  103.         this.mainLoop.start();  
  104.     }  
  105.     /** 
  106.      * 初始化背景帆布 
  107.      *  
  108.      * @param width 
  109.      * @param height 
  110.      */  
  111.     private void initCanvas(final int width, final int height) {  
  112.         canvas = new AVGCanvas(avg);  
  113.         canvas.setBackground(Color.black);  
  114.         canvas.setPreferredSize(new Dimension(width, height));  
  115.         this.add(canvas);  
  116.     }  
  117.     public IAVG getAVG() {  
  118.         return this.avg;  
  119.     }  
  120.     protected void processWindowEvent(WindowEvent e) {  
  121.         super.processWindowEvent(e);  
  122.     }  
  123.     public synchronized void paintScreen() {  
  124.         canvas.repaint();  
  125.     }  
  126.     public boolean isShowFPS() {  
  127.         return fps;  
  128.     }  
  129.     public void setShowFPS(boolean fps) {  
  130.         this.fps = fps;  
  131.     }  
  132.     public Thread getMainLoop() {  
  133.         return mainLoop;  
  134.     }  
  135.     public String getTitleName() {  
  136.         return titleName;  
  137.     }  
  138. }  
 
  我们可以看到,在本例鼠标键盘事件及图像绘制完全通过接口方式实现。 此时,只要让不同组件统一实现IControl接口,便可以轻松转换事件及图像的绘制。也正是我们都再熟悉不过的 MVC 模式中,通过 Event 导致 Controller 改变 Model View 的基本原理。
 

  例子 图下:

技术分享

end,游戏编程语言之间的开发可以融会贯通

Java开发冒险(AVG)游戏杂谈

标签:

原文地址:http://my.oschina.net/bigfool007139/blog/515503

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!