class Wall {
//位置
var x:Int = 100
var y:Int = 100
//宽高
var width:Int = Config.block
var height:Int = Config.block
//显示行为
fun draw(){
Painter.drawImage("img/wall.gif",x,y)
}
}
我们在绘制墙时就可以这样写了,修改GameWindow代码
var wall = Wall()
override fun onDisplay() {
//砖墙
wall.draw()
}
运行,砖墙就画好了
画草坪也是同样的方法,可以新建Grass类,代码跟Wall相同,只不过位置和图片不同
既然类似,我们可以将代码抽取出来,新建一个接口View
/**
* 显示的视图,定义视图规范
*/
interface View {
//位置
val x:Int
val y:Int
//宽高
val width:Int
val height:Int
//显示
fun draw()
}
让刚才的Wall实现View,Alt+Enter,让我们选择实现的成员,可以在构造方法里,也可以在members里实现,这里我们选择第二个
修改为以下代码
class Wall:View{
override val x: Int = 100
override val y: Int = 100
override val width: Int = Config.block
override val height: Int = Config.block
override fun draw() {
Painter.drawImage("img/wall.gif",x,y)
}
}
Grass同样
class Grass:View{
override val x: Int = 200
override val y: Int = 200
override val width: Int = Config.block
override val height: Int = Config.block
override fun draw() {
Painter.drawImage("img/grass.gif",x,y)
}
}
同样的方式创建出铁墙Steel、水Water的类,其他代码相同,只有图片调用不同
Painter.drawImage("img/steel.gif",x,y)
Painter.drawImage("img/water.gif",x,y)
之前位置都是写死的,我们改成通过传值来设置,修改Wall类,我们删除x,y,改成构造参数
修改后的代码如下
class Wall(override var x: Int, override var y: Int) :View{
override val width: Int = Config.block
override val height: Int = Config.block
override fun draw() {
Painter.drawImage("img/wall.gif",x,y)
}
}
其他几个类类似
我们按照以下地图绘制
在resouces中新建map/1.map
如果用一个字代表一个方格,我们有13行,13列,如果地图是空的,那么1.map的内容是:
如果把其中的一些改为“砖”
我们就可以通过读取1.map文件来绘制了
修改GameWindow.kt
class GameWindow :
Window(title = "坦克大战", icon = "img/kotlin.jpg", width = Config.gameWidth, height = Config.gameHeight) {
//管理元素的集合
val views = arrayListOf()
override fun onCreate() {
//地图
//通过读文件的方式创建地图
val file = File(javaClass.getResource("/map/1.map").path)
//读取文件行
val lines: List = file.readLines()
//循环遍历
var lineNum = 0
lines.forEach { line ->
var columnNum = 0
//it:空空空空空空空空空空空空空
line.toCharArray().forEach { column ->
when (column) {
'砖' -> views.add(Wall(columnNum * Config.block, lineNum * Config.block))
}
columnNum++
}
lineNum++
}
}
override fun onDisplay() {
//绘制地图中的元素
views.forEach{
it.draw()
}
}
override fun onKeyPressed(event: KeyEvent) {
}
override fun onRefresh() {
}
}
效果如图
同样的方法,我们在1.map中使用墙、草、水、铁这些字来代表元素,空代表空地,把1.map改为
敌空空空空空敌空空空空空敌
空砖空砖空砖空砖空砖空砖空
空铁空铁空铁空铁空铁空铁空
空砖空砖空砖空砖空砖空砖空
敌铁空铁空铁敌铁空铁空铁敌
空空空空空空空空空空空空空
铁空水水空空铁空空水水空铁
草草草草草砖草砖草草草草草
空砖空砖空砖空砖空砖空砖空
空砖空砖空砖空砖空砖空砖空
空砖空砖空空空空空砖空砖空
空空空空空空空空空空空空空
空空空空空空空空空空空空空
然后GameWindow中修改代码
class GameWindow :
......
override fun onCreate() {
......
lines.forEach { line ->
var columnNum = 0
//it:空空空空空空空空空空空空空
line.toCharArray().forEach { column ->
when (column) {
'砖' -> views.add(Wall(columnNum * Config.block, lineNum * Config.block))
'铁' -> views.add(Steel(columnNum * Config.block, lineNum * Config.block))
'草' -> views.add(Grass(columnNum * Config.block, lineNum * Config.block))
'水' -> views.add(Water(columnNum * Config.block, lineNum * Config.block))
}
columnNum++
}
lineNum++
}
}
......
}
创建枚举类型文件Direction,坦克包含上下左右四个方向
enum class Direction {
up,down,left,right
}
新建坦克对象Tank
class Tank(override var x: Int, override var y: Int) :View{
override val width: Int = Config.block
override val height: Int = Config.block
//方向
var currentDirection:Direction = Direction.up
override fun draw() {
//根据坦克类型进行绘制
//方式一
/*when(currentDirection){
Direction.up -> Painter.drawImage("img/tank_u.gif",x,y)
Direction.down -> Painter.drawImage("img/tank_d.gif",x,y)
Direction.left -> Painter.drawImage("img/tank_l.gif",x,y)
Direction.right -> Painter.drawImage("img/tank_r.gif",x,y)
}*/
//方式二
var imagePath:String = when(currentDirection){
Direction.up -> "img/tank_u.gif"
Direction.down -> "img/tank_d.gif"
Direction.left -> "img/tank_l.gif"
Direction.right -> "img/tank_r.gif"
}
Painter.drawImage(imagePath,x,y)
}
}
现在将我方坦克显示在页面上,修改GameWindow中onCreate方法
override fun onCreate() {
......
lines.forEach { line ->
......
}
//添加我方坦克
tank = Tank(Config.block * 10,Config.block * 12)
views.add(tank)
}