[common] add hard bot

This commit is contained in:
2019-03-21 17:45:03 +03:00
parent c6639e11b1
commit 0b17fbf804
23 changed files with 288 additions and 149 deletions

View File

@@ -30,7 +30,8 @@ class Style {
Skin.text(textColor, 16, fontFamily), Skin.text(textColor, 16, fontFamily),
]); ]);
resources.skin.put("text.header", [ resources.skin.put("text.header", [
Skin.color(lightColor), Skin.color(0x000000, 0.1),
Skin.border(lightColor, 1, 2),
Skin.text(textColor, 22, fontFamily), Skin.text(textColor, 22, fontFamily),
Skin.size(200, 38), Skin.size(200, 38),
]); ]);
@@ -40,11 +41,13 @@ class Style {
Skin.size(250, 50) Skin.size(250, 50)
]); ]);
resources.skin.put("text.box", [ resources.skin.put("text.box", [
Skin.color(lightColor), Skin.color(0x000000, 0.1),
Skin.border(lightColor, 1, 2),
Skin.text(textColor, 16, fontFamily), Skin.text(textColor, 16, fontFamily),
]); ]);
resources.skin.put("text.box.active", [ resources.skin.put("text.box.active", [
Skin.color(0x55aa55), Skin.color(0x55aa55),
Skin.border(0x88dd88, 1, 2),
Skin.text(textColor, 16, fontFamily), Skin.text(textColor, 16, fontFamily),
]); ]);
resources.skin.put("button.simple", [ resources.skin.put("button.simple", [

View File

@@ -1,23 +1,21 @@
package ru.m.tankz.control; package ru.m.tankz.control;
import ru.m.tankz.bot.StupidBotControl;
import ru.m.tankz.bot.HardBotControl;
import ru.m.tankz.control.Control.Controller;
import ru.m.tankz.Type; import ru.m.tankz.Type;
import ru.m.tankz.bot.BotControl;
class ClientControlFactory implements IControlFactory { class ClientControlFactory implements IControlFactory {
private var humanControlIndex:Int; public function build(id:PlayerId, controller:Controller):Control {
return switch controller {
public function new() { case HUMAN(index): new HumanControl(id, index);
humanControlIndex = 0; case BOT(type): switch type {
case StupidBotControl.BOT_TYPE: new StupidBotControl(id);
case HardBotControl.BOT_TYPE: new HardBotControl(id);
case _: null;
} }
case NONE: null;
public function build(id:PlayerId, type:ControlType):Control {
return switch (type) {
case Control.HUMAN: new HumanControl(id, humanControlIndex++);
case Control.BOT: new BotControl(id);
case Control.NONE: null;
case _: throw 'Unsupported control type: "${type}"';
} }
} }
} }

View File

@@ -37,7 +37,10 @@ import ru.m.tankz.preset.DotaGame;
} }
public function onShow() { public function onShow() {
resultView.data = resultState.players.filter(function(player) return player.control == Control.HUMAN); resultView.data = resultState.players.filter(function(player) return switch player.controller {
case HUMAN(_): true;
case _: false;
});
levelLabel.text = 'Level: ${resultState.level}'; levelLabel.text = 'Level: ${resultState.level}';
nextButton.visible = state != null; nextButton.visible = state != null;
} }

View File

@@ -2,7 +2,7 @@
views: views:
- $type: haxework.gui.VGroupView - $type: haxework.gui.VGroupView
skinId: container skinId: container
layout.margin: 3 layout.margin: 5
views: views:
- $type: haxework.gui.ImageView - $type: haxework.gui.ImageView
image: $asset:image:resources/image/ui/logo.png image: $asset:image:resources/image/ui/logo.png

View File

@@ -8,8 +8,7 @@ views:
$type: haxework.gui.LabelView $type: haxework.gui.LabelView
skinId: text.box skinId: text.box
geometry.size.height: 38 geometry.size.height: 38
geometry.padding: [20, 0] geometry.size.width: 100%
geometry.hAlign: center
- $type: haxework.gui.SpriteView - $type: haxework.gui.SpriteView
geometry.size.height: 50% geometry.size.height: 50%
- id: bot - id: bot

View File

@@ -5,6 +5,7 @@ import haxework.gui.GroupView;
import haxework.resources.IResources; import haxework.resources.IResources;
import ru.m.tankz.bundle.IConfigBundle; import ru.m.tankz.bundle.IConfigBundle;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.control.Control.Controller;
import ru.m.tankz.game.GameState; import ru.m.tankz.game.GameState;
import ru.m.tankz.Type; import ru.m.tankz.Type;
@@ -35,7 +36,8 @@ class LevelFrame extends GroupView {
for (team in value.teams) { for (team in value.teams) {
for (player in team.players) { for (player in team.players) {
var playerId = new PlayerId(team.id, player.index); var playerId = new PlayerId(team.id, player.index);
state.players.push(new PlayerState(playerId, player.control, player.life)); var controller = player.human ? HUMAN(player.index) : NONE;
state.players.push(new PlayerState(playerId, controller, player.life));
} }
} }
} }

View File

@@ -1,12 +1,12 @@
package ru.m.tankz.frame.common; package ru.m.tankz.frame.common;
import haxework.color.ColorUtil; import haxework.color.ColorUtil;
import ru.m.tankz.control.Control;
import haxework.gui.DataView; import haxework.gui.DataView;
import haxework.gui.HGroupView; import haxework.gui.HGroupView;
import haxework.gui.LabelView; import haxework.gui.LabelView;
import haxework.gui.skin.ISkin; import haxework.gui.skin.ISkin;
import haxework.gui.ToggleButtonView; import haxework.gui.ToggleButtonView;
import ru.m.tankz.control.Control;
import ru.m.tankz.game.GameState; import ru.m.tankz.game.GameState;
import ru.m.tankz.Type.TeamId; import ru.m.tankz.Type.TeamId;
@@ -42,7 +42,7 @@ class TeamSkin implements ISkin<TeamButton> {
} }
@:template class PlayerView extends HGroupView { @:template class PlayerView extends HGroupView {
private static inline var NONE:TeamId = "none"; private static inline var TEAM_NONE:TeamId = "none";
public var item_index(default, set):Int; public var item_index(default, set):Int;
public var data(default, set):Array<PlayerState>; public var data(default, set):Array<PlayerState>;
@@ -59,13 +59,13 @@ class TeamSkin implements ISkin<TeamButton> {
view.skin = [new TeamSkin(getTeamColor(team))]; view.skin = [new TeamSkin(getTeamColor(team))];
view.geometry.padding = [10, 5]; view.geometry.padding = [10, 5];
view.team = team; view.team = team;
view.on = team == NONE; view.on = team == TEAM_NONE;
return view; return view;
} }
private function set_data(value:Array<PlayerState>):Array<PlayerState> { private function set_data(value:Array<PlayerState>):Array<PlayerState> {
data = value; data = value;
teams.data = [NONE].concat([for (team in state.preset.teams) team.id]); teams.data = [TEAM_NONE].concat([for (team in state.preset.teams) team.id]);
return data; return data;
} }
@@ -88,16 +88,20 @@ class TeamSkin implements ISkin<TeamButton> {
private function onTeamSelect(team:TeamId) { private function onTeamSelect(team:TeamId) {
if (player != null) { if (player != null) {
player.control = Control.BOT; player.controller = NONE;
player.color = 0; player.color = 0;
player = null; player = null;
} }
for (p in data) { for (p in data) {
if (p.id.team == team && p.control != Control.HUMAN) { if (p.id.team == team) {
switch (p.controller) {
case NONE:
player = p; player = p;
player.control = Control.HUMAN; player.controller = HUMAN(item_index);
player.color = ColorUtil.multiply(state.config.getTeam(team).color, 1.7); player.color = ColorUtil.multiply(state.config.getTeam(team).color, 1.7);
break; break;
case _:
}
} }
} }
for (view in teams.views) { for (view in teams.views) {

View File

@@ -7,14 +7,14 @@ views:
tank: bc tank: bc
color: 0xff4422 color: 0xff4422
- $type: haxework.gui.SpriteView - $type: haxework.gui.SpriteView
geometry.size.width: 50% geometry.size.width: 25%
- id: level - id: level
$type: haxework.gui.LabelView $type: haxework.gui.LabelView
skinId: text.box skinId: text.box
geometry.size.height: 38 geometry.size.height: 38
geometry.padding: [20, 0]
- $type: haxework.gui.SpriteView
geometry.size.width: 50% geometry.size.width: 50%
- $type: haxework.gui.SpriteView
geometry.size.width: 25%
- id: dire - id: dire
$type: ru.m.tankz.frame.common.LifeView $type: ru.m.tankz.frame.common.LifeView
tank: bc tank: bc

View File

@@ -44,11 +44,14 @@ import ru.m.tankz.storage.SettingsStorage;
} }
} }
private function onItemSelect(index:Int, value:ActionItem, view:ActionView):Void {
view.edit();
}
private function _change():Void { private function _change():Void {
var p: Promise<Int> = Promise.promise(0); var p: Promise<Int> = Promise.promise(0);
for (view in list.views) { for (view in list.views) {
var v: ActionView = cast view; var v: ActionView = cast view;
if (v.data == null) break;
p = p.pipe(function(_):Promise<Int> return v.edit()); p = p.pipe(function(_):Promise<Int> return v.edit());
} }
p.then(function(_) _save()); p.then(function(_) _save());

View File

@@ -27,3 +27,4 @@ views:
layout: layout:
$type: haxework.gui.layout.VerticalLayout $type: haxework.gui.layout.VerticalLayout
factory: $this:viewFactory factory: $this:viewFactory
+onItemSelect: $this:onItemSelect

View File

@@ -6,8 +6,6 @@ typedef GameType = String;
typedef TeamId = String; typedef TeamId = String;
typedef ControlType = String;
typedef BrickType = String; typedef BrickType = String;
typedef TankType = String; typedef TankType = String;

View File

@@ -3,117 +3,55 @@ package ru.m.tankz.bot;
import haxe.Timer; import haxe.Timer;
import ru.m.geom.Direction; import ru.m.geom.Direction;
import ru.m.tankz.control.Control; import ru.m.tankz.control.Control;
import ru.m.tankz.core.Eagle;
import ru.m.tankz.core.Entity;
import ru.m.tankz.core.EntityType;
import ru.m.tankz.core.Tank; import ru.m.tankz.core.Tank;
import ru.m.tankz.Type;
class BotHelper {
public static function findEagle(team:TeamId, handler:ControlHandler):Null<Eagle> {
for (entity in handler.entities) {
switch (EntityTypeResolver.of(entity)) {
case EntityType.EAGLE(eagle):
if (eagle.team != team) {
return eagle;
}
case x:
}
}
return null;
}
public static function getDirectionTo(entity:Entity, target:Entity):Direction {
var x:Float = target.rect.x - entity.rect.x;
var y:Float = target.rect.y - entity.rect.y;
var xD:Direction = Direction.from(Std.int(x / Math.abs(x)), 0);
var yD:Direction = Direction.from(0, Std.int(y / Math.abs(y)));
if (entity.rect.direction == xD) return yD;
if (entity.rect.direction == yD) return xD;
return Math.abs(x) > Math.abs(y) ? xD : yD;
}
public static function randomDirection():Direction {
return [
Direction.TOP,
Direction.BOTTOM,
Direction.LEFT,
Direction.RIGHT,
][Math.floor(Math.random() * 4)];
}
}
class BotControl extends Control { class BotControl extends Control {
private var shotTimer:Timer; private var shotTimer:Timer;
private var turnRandomTimer:Timer;
private var turnTimer:Timer; private var turnTimer:Timer;
private var tank(get, null):Tank; private var tank(get, null):Tank;
public function new(playerId:PlayerId) { private inline function get_tank():Tank {
super(playerId); return cast handler.entities[tankId];
}
override public function onCollision(with:EntityType):Void {
switch (with) {
case EntityType.TANK(_): turnAfter(300);
case EntityType.CELL(_): turnAfter(300);
case _:
}
}
override public function start():Void {
if (handler == null) return;
action(TankAction.MOVE(tank.rect.direction));
if (shotTimer == null) {
shotTimer = new Timer(1000);
shotTimer.run = shot;
}
if (turnRandomTimer == null) {
turnRandomTimer = new Timer(2000);
turnRandomTimer.run = turn;
}
} }
override public function stop():Void { override public function stop():Void {
super.stop();
if (shotTimer != null) { if (shotTimer != null) {
shotTimer.stop(); shotTimer.stop();
shotTimer = null; shotTimer = null;
} }
if (turnRandomTimer != null) {
turnRandomTimer.stop();
turnRandomTimer = null;
}
}
public function shot():Void {
action(TankAction.SHOT);
}
public function turnAfter(delay:Int):Void {
if (turnTimer == null) {
turnTimer = Timer.delay(turn, delay);
}
}
public function turn():Void {
if (turnTimer != null) { if (turnTimer != null) {
turnTimer.stop(); turnTimer.stop();
turnTimer = null; turnTimer = null;
} }
// ToDo: }
if (handler == null || tank == null) return;
var eagle:Eagle = BotHelper.findEagle(playerId.team, handler); private function _shot():Void {
if (eagle != null && Math.random() > 0.5) { if (shotTimer != null) {
action(TankAction.MOVE(BotHelper.getDirectionTo(tank, eagle))); shotTimer.stop();
} else { shotTimer = null;
action(TankAction.MOVE(BotHelper.randomDirection())); }
action(SHOT);
}
public function shot(delay:Int = 100):Void {
if (shotTimer == null) {
shotTimer = Timer.delay(function() _shot(), delay);
} }
} }
private function get_tank():Tank { private function _turn(direction:Direction):Void {
return cast handler.entities[tankId]; if (turnTimer != null) {
turnTimer.stop();
turnTimer = null;
}
action(MOVE(direction));
}
public function turn(direction:Direction, delay:Int = 300):Void {
if (turnTimer == null) {
turnTimer = Timer.delay(function() _turn(direction), delay);
}
} }
} }

View File

@@ -0,0 +1,47 @@
package ru.m.tankz.bot;
import ru.m.geom.Direction;
import ru.m.tankz.core.Entity;
import ru.m.tankz.core.EntityType;
import ru.m.tankz.core.Eagle;
import ru.m.tankz.control.Control.ControlHandler;
import ru.m.tankz.Type;
class BotHelper {
public static function findEagle(team:TeamId, handler:ControlHandler):Null<Eagle> {
for (entity in handler.entities) {
switch (EntityTypeResolver.of(entity)) {
case EntityType.EAGLE(eagle):
if (eagle.team != team) {
return eagle;
}
case _:
}
}
return null;
}
public static function getDirectionTo(entity:Entity, target:Entity):Direction {
var x:Float = target.rect.center.x - entity.rect.center.x;
var y:Float = target.rect.center.y - entity.rect.center.y;
var xD:Direction = Direction.from(Std.int(x / Math.abs(x)), 0);
var yD:Direction = Direction.from(0, Std.int(y / Math.abs(y)));
return Math.abs(x) > Math.abs(y) ? xD : yD;
}
public static function randomDirection():Direction {
return [
Direction.TOP,
Direction.BOTTOM,
Direction.LEFT,
Direction.RIGHT,
][Math.floor(Math.random() * 4)];
}
public static function getDistance(entity:Entity, target:Entity):Float {
var x:Float = target.rect.center.x - entity.rect.center.x;
var y:Float = target.rect.center.y - entity.rect.center.y;
return Math.abs(x) + Math.abs(y);
}
}

View File

@@ -0,0 +1,78 @@
package ru.m.tankz.bot;
import haxe.Timer;
import ru.m.tankz.core.EntityType;
import ru.m.tankz.core.Tank;
class HardBotControl extends BotControl {
public static inline var BOT_TYPE = "hard";
private var actionTimer:Timer;
override public function onCollision(with:EntityType):Void {
switch (with) {
case TANK(t):
if (t.playerId.team != tank.playerId.team) {
shot();
}
case CELL(cell):
if (cell.layer == 2 && cell.armor <= tank.config.bullet.piercing) {
shot();
}
case EAGLE(eagle):
if (eagle.team != tank.playerId.team) {
shot();
}
case _:
}
calcTurn();
}
override public function start():Void {
if (handler == null) return;
turn(tank.rect.direction);
if (actionTimer == null) {
actionTimer = new Timer(500);
actionTimer.run = nextAction;
}
}
override public function stop():Void {
super.stop();
if (actionTimer != null) {
actionTimer.stop();
actionTimer = null;
}
}
private function nextAction():Void {
var enemy:Tank = null;
var distance:Float = Math.POSITIVE_INFINITY;
for (entity in handler.entities.iterator()) {
switch EntityTypeResolver.of(entity) {
case TANK(t):
if (t.playerId.team != tank.playerId.team) {
var d = BotHelper.getDistance(tank, t);
if (d < distance && (Math.abs(t.rect.x - tank.rect.x) < tank.rect.width / 2 || Math.abs(t.rect.y - tank.rect.y) < tank.rect.height / 2)) {
enemy = t;
distance = d;
}
}
case _:
}
}
if (enemy != null) {
var d = BotHelper.getDirectionTo(tank, enemy);
if (d != tank.rect.direction) {
turn(BotHelper.getDirectionTo(tank, enemy), 1);
}
shot();
} else if (Math.random() > 0.8) {
calcTurn();
}
}
private function calcTurn():Void {
turn(BotHelper.randomDirection());
}
}

View File

@@ -0,0 +1,54 @@
package ru.m.tankz.bot;
import haxe.Timer;
import ru.m.tankz.control.Control;
import ru.m.tankz.core.Eagle;
import ru.m.tankz.core.EntityType;
class StupidBotControl extends BotControl {
public static inline var BOT_TYPE = "stupid";
private var turnRandomTimer:Timer;
override public function onCollision(with:EntityType):Void {
switch (with) {
case TANK(_): calcTurn();
case CELL(_): calcTurn();
case EAGLE(_): calcTurn();
case _:
}
}
override public function start():Void {
super.start();
if (handler == null) return;
action(MOVE(tank.rect.direction));
if (turnRandomTimer == null) {
turnRandomTimer = new Timer(2000);
turnRandomTimer.run = calcTurn;
}
}
override public function stop():Void {
super.stop();
if (turnRandomTimer != null) {
turnRandomTimer.stop();
turnRandomTimer = null;
}
}
private function calcTurn():Void {
if (turnTimer != null) {
turnTimer.stop();
turnTimer = null;
}
// ToDo:
if (handler == null || tank == null) return;
var eagle:Eagle = BotHelper.findEagle(playerId.team, handler);
if (eagle != null && Math.random() > 0.5) {
turn(BotHelper.getDirectionTo(tank, eagle));
} else {
turn(BotHelper.randomDirection());
}
}
}

View File

@@ -75,7 +75,7 @@ typedef PlayerConfig = {
@:optional var protect:Float; @:optional var protect:Float;
@:optional var life:Int; @:optional var life:Int;
@:optional var color:Color; @:optional var color:Color;
@:optional var control:ControlType; @:optional var human:Bool;
} }
typedef EagleConfig = { typedef EagleConfig = {

View File

@@ -3,6 +3,7 @@ package ru.m.tankz.control;
import ru.m.geom.Direction; import ru.m.geom.Direction;
import ru.m.tankz.core.Entity; import ru.m.tankz.core.Entity;
import ru.m.tankz.core.EntityType; import ru.m.tankz.core.EntityType;
import ru.m.tankz.map.LevelMap;
import ru.m.tankz.Type; import ru.m.tankz.Type;
enum TankAction { enum TankAction {
@@ -12,11 +13,13 @@ enum TankAction {
SHOT; SHOT;
} }
class Control { enum Controller {
public static var NONE(default, never):ControlType = 'none'; NONE;
public static var HUMAN(default, never):ControlType = 'human'; HUMAN(index:Int);
public static var BOT(default, never):ControlType = 'bot'; BOT(type:String);
}
class Control {
public var playerId(default, null):PlayerId; public var playerId(default, null):PlayerId;
public var tankId(default, default):Int; public var tankId(default, default):Int;
private var handler:ControlHandler; private var handler:ControlHandler;
@@ -35,9 +38,7 @@ class Control {
} }
} }
public function onCollision(with:EntityType):Void { public function onCollision(with:EntityType):Void {}
}
public function start():Void {} public function start():Void {}
@@ -50,6 +51,7 @@ class Control {
} }
interface ControlHandler { interface ControlHandler {
public var map(default, null):LevelMap;
public var entities(default, null):Map<Int, Entity>; public var entities(default, null):Map<Int, Entity>;
public function action(tankId:Int, action:TankAction):Void; public function action(tankId:Int, action:TankAction):Void;
} }

View File

@@ -1,8 +1,9 @@
package ru.m.tankz.control; package ru.m.tankz.control;
import ru.m.tankz.control.Control;
import ru.m.tankz.Type; import ru.m.tankz.Type;
interface IControlFactory { interface IControlFactory {
public function build(id:PlayerId, type:ControlType):Control; public function build(id:PlayerId, controller:Controller):Control;
} }

View File

@@ -1,5 +1,6 @@
package ru.m.tankz.control; package ru.m.tankz.control;
import ru.m.tankz.control.Control;
import ru.m.tankz.Type; import ru.m.tankz.Type;
@@ -7,7 +8,7 @@ class NoneControlFactory implements IControlFactory {
public function new() {} public function new() {}
public function build(id:PlayerId, type:ControlType):Control { public function build(id:PlayerId, controller:Controller):Control {
return null; return null;
} }
} }

View File

@@ -109,14 +109,18 @@ class Game {
var team:Team = new Team(teamConfig, teamPoints); var team:Team = new Team(teamConfig, teamPoints);
teams[team.id] = team; teams[team.id] = team;
for (player in team.players.iterator()) { for (player in team.players.iterator()) {
var controlType:ControlType = Control.BOT; var controller:Controller = Controller.BOT("hard");
var nextPlayer:PlayerState = Lambda.find(players, function(p) return p.id == player.id); var nextPlayer:PlayerState = Lambda.find(players, function(p) return p.id == player.id);
if (nextPlayer != null) { if (nextPlayer != null) {
player.state = nextPlayer; player.state = nextPlayer;
players.remove(nextPlayer); players.remove(nextPlayer);
controlType = nextPlayer.control; switch (nextPlayer.controller) {
case HUMAN(_):
controller = nextPlayer.controller;
case _:
} }
var control = controlFactory.build(player.id, controlType); }
var control = controlFactory.build(player.id, controller);
L.d(TAG, 'control(${player.id} - ${control})'); L.d(TAG, 'control(${player.id} - ${control})');
if (control != null) { if (control != null) {
player.control = control; player.control = control;

View File

@@ -9,7 +9,7 @@ import ru.m.tankz.Type;
class PlayerState { class PlayerState {
public var id:PlayerId; public var id:PlayerId;
public var tank:TankType; public var tank:TankType;
public var control:ControlType; public var controller:Controller;
public var color:Color; public var color:Color;
public var life:Int; public var life:Int;
public var score:Int; public var score:Int;
@@ -17,10 +17,10 @@ class PlayerState {
public var shots:Int; public var shots:Int;
public var hits:Int; public var hits:Int;
public function new(id:PlayerId, control:ControlType = null, life:Int = 0) { public function new(id:PlayerId, controller:Controller = null, life:Int = 0) {
this.id = id; this.id = id;
this.tank = null; this.tank = null;
this.control = control == null ? Control.BOT : control; this.controller = controller == null ? Controller.NONE : controller;
this.life = life; this.life = life;
this.score = 0; this.score = 0;
this.frags = 0; this.frags = 0;

View File

@@ -23,7 +23,7 @@ player:
human: &human human: &human
life: 3 life: 3
protect: 5 protect: 5
control: human human: true
tanks: tanks:
- {type: human0, rate: 1} - {type: human0, rate: 1}
bot: &bot bot: &bot

View File

@@ -1,5 +1,6 @@
package ru.m.tankz.editor.level; package ru.m.tankz.editor.level;
import openfl.Assets;
import flash.display.DisplayObjectContainer; import flash.display.DisplayObjectContainer;
import flash.display.Graphics; import flash.display.Graphics;
import flash.display.Sprite; import flash.display.Sprite;
@@ -25,8 +26,8 @@ class SpawnPointEntity extends Entity {
class SpawnPointItem extends BitmapItem<SpawnPointEntity> { class SpawnPointItem extends BitmapItem<SpawnPointEntity> {
private var cellX:Int; private var cellX:Int = -1;
private var cellY:Int; private var cellY:Int = -1;
private var src:String; private var src:String;
public function new(value:SpawnPoint, config:Config) { public function new(value:SpawnPoint, config:Config) {
@@ -62,11 +63,12 @@ class SpawnPointItem extends BitmapItem<SpawnPointEntity> {
override public function update():Void { override public function update():Void {
super.update(); super.update();
var image = Assets.getBitmapData(getImage());
if (cellX != value.point.x || cellY != value.point.y) { if (cellX != value.point.x || cellY != value.point.y) {
cellX = value.point.x; cellX = value.point.x;
cellY = value.point.y; cellY = value.point.y;
value.rect.x = cellX * (value.rect.width / 2); value.rect.x = cellX * (value.rect.width / 2) + (value.rect.width - image.width) / 2;
value.rect.y = cellY * (value.rect.height / 2); value.rect.y = cellY * (value.rect.height / 2) + (value.rect.height - image.height) / 2;
redraw(); redraw();
} }
} }
@@ -133,6 +135,7 @@ class MapEditView extends SpriteView {
p.x = b.cellX; p.x = b.cellX;
p.y = b.cellY; p.y = b.cellY;
drawMap(); drawMap();
drawMap();
break; break;
} }
} }