Rafael Almeida Barbosa
Desenvolvedor Mobile, Palestrante, Pai coruja! Apaixonado por inovações e soluções que cabem na palma da mão!
Mobile developer (Flutter, Android, IOS)
FlutterBR
Role-playing game, também conhecido como RPG, é um tipo de jogo em que os jogadores assumem papéis de personagens e criam narrativas colaborativamente.
Será que consigo criar um RPG game com ele?
(RPG maker) Crie jogos do estilo RPG ou similares com o Flutter.
Ele é ideal para criar games com as seguintes perspectivas:
return BonfireWidget(
gameController: GameController(),
joystick: MyJoystick()
map: TiledWorldMap('tile/map.json', forceTileSize: tileSize),
player: Knight(),
interface: KnightInterface(),
background: GameComponent(),
constructionMode: false,
showCollisionArea: false,
constructionModeColor: Colors.blue,
collisionAreaColor: Colors.blue,
lightingColorGame: Colors.black.withOpacity(0.4),
components: <GameComponent>[],
cameraConfig: CameraConfig(
sizeMovementWindow: Size(50,50),
moveOnlyMapArea: false,
zoom: 1.0,
target: GameComponent(),
),
showFPS: false,
progress: Widget(),
);
TiledWorldMap(
'tiled/map.json',
forceTileSize: Size(32,32),
objectsBuilder: {
'orc': (ObjectProperties properties){
return Orc(properties.position);
},
},
)
[
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 2, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 2, 2, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 2, 2, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 2, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
]
GameDecoration.withSprite({
required FutureOr<Sprite> sprite,
required Vector2 position,
required Vector2 size,
})
GameDecoration.withAnimation({
required FutureOr<SpriteAnimation> animation,
required Vector2 position,
required Vector2 size,
}
)
class MyDecoration extends GameDecoration {
MyDecoration(Position position)
: super.withAnimation(
animation: SpriteAnimation.load(
"itens/torch_spritesheet.png",
SpriteAnimationData.sequenced(
amount: 6,
stepTime: 0.1,
textureSize: Vector2.all(16),
),
),
size: Vector2.all(32),
position: position,
);
@override
void update(double dt) {
// do anything
super.update(dt);
}
@override
void render(Canvas canvas) {
// do anything
super.render(canvas);
}
}
SimpleEnemy
RotationEnemy
class Goblin extends SimpleEnemy {
Goblin(Vector2 initPosition)
: super(
position:initPosition, //required
size:Vector2.all(32), //required
animation: SimpleDirectionAnimation(), //required
life: 100,
speed: 100,
);
}
class Tank extends RotationEnemy {
Tank(Position initPosition)
: super(
initPosition:initPosition, //required
size: Vector2.all(32),
life: 100,
speed: 100,
animIdle: Future<SpriteAnimation>(), //required (TOP)
animRun: Future<SpriteAnimation>(), //required (TOP)
);
@override
void update(double dt) {
super.update(dt);
}
@override
void render(Canvas canvas) {
super.render(canvas);
}
@override
void die() {
super.die();
}
}
void seePlayer({
Function(Player) observed,
Function() notObserved,
double radiusVision = 32,
int interval = 500,
})
void seeAndMoveToPlayer({
Function(Player) closePlayer,
double radiusVision = 32,
double margin = 10,
})
void seeAndMoveToAttackRange({
Function(Player) positioned,
double radiusVision = 32,
double minDistanceCellsFromPlayer,
})
void simpleAttackMelee({
@required double damage,
double height = 32,
double width = 32,
int id,
int interval = 1000,
bool withPush = false,
double sizePush,
Direction direction,
Future<SpriteAnimation> attackEffectRightAnim,
Future<SpriteAnimation> attackEffectBottomAnim,
Future<SpriteAnimation> attackEffectLeftAnim,
Future<SpriteAnimation> attackEffectTopAnim,
VoidCallback execute,
})
void simpleAttackRange({...})
@override
void update(double dt) {
this.seeAndMoveToPlayer(
closePlayer: (player) {
execAttack();
},
radiusVision: tileSize * 2,
);
super.update(dt);
}
@override
void update(double dt) {
this.seeAndMoveToAttackRange(
minDistanceFromPlayer: tileSize * 2,
positioned: (p) {
execAttackRange();
},
radiusVision: tileSize * 5,
);
super.update(dt);
}
class MyCustomEnemy extends Enemy{}
void moveUp(double speed, {VoidCallback? onCollision});
void moveDown(double speed, {VoidCallback? onCollision});
void moveLeft(double speed, {VoidCallback? onCollision});
void moveRight(double speed, {VoidCallback? onCollision});
void moveUpRight(double speedX, double speedY, {VoidCallback? onCollision});
void moveUpLeft(double speedX, double speedY, {VoidCallback? onCollision});
void moveDownLeft(double speedX, double speedY, {VoidCallback? onCollision});
void moveDownRight(double speedX, double speedY, {VoidCallback? onCollision});
void moveFromAngleDodgeObstacles(double speed, double angle,{Function notMove});
void moveFromAngle(double speed, double angle);
void receiveDamage(double damage, int from);
void addLife(double life);
void die();
SimplePlayer
RotationPlayer
class Kinght extends SimplePlayer {
Kinght(Position initPosition)
: super(
position:initPosition, //required
size: Vector2.all(32), //required
life: 100,
speed: 100,
animation: SimpleDirectionAnimation(), //required
);
}
class PlayerTank extends RotationPlayer {
PlayerTank(Position initPosition)
: super(
position:initPosition, //required
size: Vector2.all(32),
life: 100,
speed: 100,
animIdle: Future<SpriteAnimation>(), //required
animRun: Future<SpriteAnimation> (), //required
);
}
void simpleAttackMelee(...);
void simpleAttackRange(...);
void showDamage(...);
void seeEnemy(...);
@override
void joystickChangeDirectional(JoystickDirectionalEvent event) {
// do anything with event of the joystick
super.joystickChangeDirectional(event);
}
@override
void joystickAction(JoystickActionEvent event) {
// do anything with event of the joystick
super.joystickAction(event);
}
class MyCustomPlayer extends Player{}
void moveUp(double speed, {VoidCallback? onCollision});
void moveDown(double speed, {VoidCallback? onCollision});
void moveLeft(double speed, {VoidCallback? onCollision});
void moveRight(double speed, {VoidCallback? onCollision});
void moveUpRight(double speedX, double speedY, {VoidCallback? onCollision});
void moveUpLeft(double speedX, double speedY, {VoidCallback? onCollision});
void moveDownLeft(double speedX, double speedY, {VoidCallback? onCollision});
void moveDownRight(double speedX, double speedY, {VoidCallback? onCollision});
void moveFromAngleDodgeObstacles(double speed, double angle,{Function notMove});
void moveFromAngle(double speed, double angle);
void receiveDamage(double damage, int from);
void addLife(double life);
void die();
class MyDecoration extends GameDecoration with ObjectCollision {
MyCustomDecoration(Position position)
: super.withAnimation(
animation: Future<SpriteAnimation>(),
size: Vector2.all(32),
height: 32,
position: position,
){
setupCollision(
CollisionConfig(
enable: true,
collisions: [ //required
CollisionArea.rectangle(
size: Vector2(32,32),
align: Vector2(0,0),
),
],
),
);
}
}
return BonfireWidget(
showCollisionArea: true,
);
return BonfireWidget(
lightingColorGame: Colors.black.withOpacity(0.4),
);
class Torch extends Gamedecoration with Lighting{
Torch(Position position)
: super.withAnimation(
animation: Future<SpriteAnimation>(),
width: 32,
height: 32,
position: position,
){
setupLighting(
LightingConfig(
color: Colors.yellow.withOpacity(0.1),
radius: 40,
blurBorder: 20,
withPulse: true,
pulseVariation: 0.1,
pulseCurve: Curves.decelerate,
pulseSpeed: 1,
),
);
}
}
class MyInterface extends GameInterface {
@override
void onGameResize(Vector2 size) {
add(BarLifeComponent());
add(
InterfaceComponent(
sprite: Sprite('blue_button1.png'),
spriteSelected: Sprite('blue_button2.png'),
height: 40,
width: 40,
id: 5,
position: Position(150, 20),
onTapComponent: () {
print('Test button');
},
),
);
super.resize(size);
}
}
class BarLifeComponent extends InterfaceComponent {
BarLifeComponent(int id, Position position)
: super(
id: id,
position: position,
width: 120,
height: 40,
);
@override
void update(double t) {
super.update(t);
}
@override
void render(Canvas c) {
super.render(c);
}
@override
void onTap() {
super.onTap();
}
}
Joystick(
keyboardEnable: false,
directional: JoystickDirectional(
spriteBackgroundDirectional: Sprite.load('joystick_background.png'),
spriteKnobDirectional: Sprite.load('joystick_knob.png'),
color: Colors.black,
size: 100,
isFixed: false,
),
actions: [
JoystickAction(
actionId: 1, //(required)
sprite: Sprite.load('joystick_atack_range.png'),
spritePressed: Sprite.load('joystick_atack_range.png'),
spriteBackgroundDirection: Sprite('joystick_background.png'),
enableDirection: true,
align: JoystickActionAlign.BOTTOM_RIGHT,
color: Colors.blue,
size: 50,
margin: EdgeInsets.only(bottom: 50, right: 160),
)
],
)
Joystick(
directional: JoystickDirectional(),
)
Joystick(
actions: [
JoystickAction(
actionId: 1,
size: 80,
margin: EdgeInsets.only(
bottom: 50,
right: 50,
),
)
JoystickAction(
actionId: 2,
enableDirection: true,
size: 50,
margin: EdgeInsets.only(
bottom: 50,
right: 160,
),
)
],
)
Multi Scenes
Bonfire 3.0
- Remover implementações próprias
- Suporte raycast
Isometric Maps
By Rafael Almeida Barbosa
Desenvolvedor Mobile, Palestrante, Pai coruja! Apaixonado por inovações e soluções que cabem na palma da mão!