Smart Mobile Studio
  • News
  • Forums
  • Download
  • Store
  • Showcases
    • Featured demos
    • The Smart Contest 2013, Round 1 – Graphics
  • Documentation
    • Get the book
    • System requirements
    • Prerequisites
    • Getting started
      • Introduction
      • Application architecture
      • The application object
      • Forms and navigation
      • Message dialogs
      • Themes and styles
    • Project types
      • Visual project
      • Game project
      • Console project
    • Layout manager
    • Networking
      • TW3HttpRequest
      • TW3JSONP
      • Loading files
  • About

Tag Archives: parallax

Retro demo coded in Smart

Posted on 30.03.2012 by Jon Lennart Posted in Developers log 2 Comments
Parallax scrolling galore

Parallax scrolling galore

This is a small retro demo I put together last weekend. Believe it or not but it doesn’t use the HTML5 canvas display at all. Everything you see moving on the screen are actually controls (which in this case inherits from the lightweight TW3MovableControl, which is the base-class TW3CustomControl builds on).

You can test-drive the demo yourself here: Parallax demo

qrcode

Features

  • parallax scrolling
  • alpha blending
  • scroll-text with bitmap fonts
  • 3d rotated logo
  • hardware accelerated transformations

Note: This is a webkit only demo, so it will only run under Chrome or Safari (also iPad and iPhone is supported, but lacks sound).

The source

352 lines of uber-messy code, just like the good old days on the Amiga 🙂

[sourcecode language=”delphi”]
unit Form1;

interface

uses w3system, w3graphics, w3ctrls, w3components, w3time,
w3forms, w3application, w3sprite3d, w3bmpfont;

const
CHAR_SIZE = 16;
CHARSET_FONT = ‘ !"#¤%&/{}=_-\[]0123456789:;(|)?*abcdefghijklmnopqrstuvwxyz’;

type

TMenuLogo = Class(TW3Sprite)
Private
mDown: Boolean;
protected
Procedure InitializeObject;override;
public
Procedure UpdateBehavior(Const TimeId:Integer);override;
End;

TMenuBackground01 = Class(TW3Sprite)
protected
Procedure InitializeObject;override;
public
Procedure UpdateBehavior(Const TimeId:Integer);override;
End;

TFront = Class(TW3Sprite)
protected
Procedure InitializeObject;override;
public
Procedure UpdateBehavior(Const TimeId:Integer);override;
End;

TForm1=class(TW3form)
private
{ Private methods }
{$I ‘Form1:intf’}
FLogo: TMenuLogo;
FBack01: TMenuBackground01;
FTimer: TW3Timer;
FCounter: Integer;
FMyFont: TKromaskyBitmapFont;
FCredits: TW3Image;
FFontDone:Boolean;
FChars: Array of TW3Sprite;
FReady: Array of TW3Sprite;
FScrolled:Float;
FText: String;
FCharIndex:Integer;
FAudio: Variant;
FFront: TFront;
Procedure HandleUpdate(Sender:TObject);
procedure setupChars;
protected
{ Protected methods }
Procedure InitializeObject;override;
Procedure FinalizeObject;override;
Procedure StyleTagObject;reintroduce;virtual;
Procedure Resize;Override;
Procedure FormActivated;override;
Procedure FormDeActivated;override;
end;

Implementation

//############################################################################
// TFront
//############################################################################

Procedure TFront.InitializeObject;
Begin
inherited;
setTransformFlags(CNT_USE_POS);
Background.fromURL(‘res/tile_ground.png’);
Width:=96 * 32;
height:=96;
Transparent:=True;
end;

Procedure TFront.UpdateBehavior(Const TimeId:Integer);
var
mRange: Integer;
Begin
mRange:=application.Display.View.Width;
mRange:=(mRange div 96) * 96;
if X<=-(mRange) then
X:=0.0;
MoveX(-1.5);
Update3d;
end;

//############################################################################
// TMenuBackground01
//############################################################################

Procedure TMenuBackground01.InitializeObject;
Begin
inherited;
setTransformFlags(CNT_USE_POS);
Background.fromURL(‘res/gamebg02.png’);
Width:=960 * 2;
height:=480;
end;

Procedure TMenuBackground01.UpdateBehavior(Const TimeId:Integer);
Begin
if X<=-960 then
X:=0;
MoveX(-0.80);
Update3d;
end;

//############################################################################
// TMenuLogo
//############################################################################

Procedure TMenuLogo.InitializeObject;
Begin
inherited;
setTransformFlags(CNT_USE_POS or CNT_USE_SCALE or CNT_USE_ROTY);
Width:=422;
Height:=57;
mDown:=True;
Update3d;

Transparent:=True;
background.fromURL(‘res/parallax.png’);
end;

Procedure TMenuLogo.UpdateBehavior(Const TimeId:Integer);
Begin
if (TimeId mod 3)=0 then
Begin
case mDown of
True:
Begin
if Y<20 then
Begin
MoveY(0.50);
end else
mDown:=False;
end;
false:
Begin
if Y>10 then
Begin
MoveY(-0.50);
end else
mDown:=True;
end;
end;
update3d;
end else
Begin
RotateY(-1);
update3d;
end;
end;

//############################################################################
// TForm1
//############################################################################

function getXforChar(aChar:String):Integer;
var
xpos: Integer;
begin
if length(aChar)>1 then
xpos:=pos(aChar[1],CHARSET_FONT) else
if length(aChar)=1 then
xpos:=pos(aChar,CHARSET_FONT) else
exit;
result:=CHAR_SIZE * (xpos -1);
end;

Procedure TForm1.InitializeObject;
Begin
inherited;
{$I ‘Form1:impl’}
StyleClass:=”;

FTimer:=TW3Timer.Create;
FTimer.Delay:=1;
FTimer.onTime:=HandleUpdate;

asm
@FAudio = new Audio();
(@FAudio).autoplay=true;
(@FAudio).src = "res/Last Ninja wastelands.mp3";
end;

FBack01:=TMenuBackground01.Create(self);
FLogo:=TMenuLogo.Create(self);
FFront:=TFront.Create(self);
FMyFont:=TKromaskyBitmapFont.Create;

FText:=’Welcome to 1990* This is a nice retro demo coded in ‘
+ ‘¤Smart Mobile Studio¤ Brought to you by Optimale Systemer AS ‘
+ ‘&&&&&&&& ‘;
FText:=lowercase(FText);
FCharIndex:=0;

Background.fromURL(‘res/ancientbg.png’);
w3_setStyle(tagRef,’background-repeat’,’repeat-x’);
w3_setStyle(tagRef,’background-size’,’auto 100%’);
End;

Procedure TForm1.FinalizeObject;
Begin
FLogo.free;
FBack01.free;
FFront.free;
inherited;
End;

Procedure TForm1.HandleUpdate(Sender:TObject);
var
x: Integer;
mSprite: TW3Sprite;
Begin
inc(FCounter);

FLogo.UpdateBehavior(FCounter);
FBack01.UpdateBehavior(FCounter);
FFront.UpdateBehavior(FCounter);

If FMyFont.Ready
and not FFontDone then
Begin
FFontDone:=True;
FCredits:=FMyFont.DrawAndMake(‘coded by quartex’);
FCredits.InsertInto(self.tagRef);
FCredits.Visible:=True;

FCredits.top:=Height – (FCredits.height + 10);
FCredits.left:=(Width div 2) – (FCredits.width div 2);
w3system.w3_Callback(self.resize,10);
end;

if length(FChars)>0 then
Begin
x:=-1;
repeat
inc(x);

mSprite:=FChars[x];
mSprite.moveX(-0.5);

if mSprite.x<=(-CHAR_SIZE) then
begin
FChars.Delete(x,1);
FReady.add(mSprite);
dec(x);
end else
mSprite.update3d;

until x>=high(FCHars);

end;

FScrolled+=0.5;
if FScrolled>=CHAR_SIZE then
begin
FScrolled:=0.0;
inc(FCharIndex);
if FCharIndex>Length(FText) then
FCharIndex:=1;

if FReady.length>0 then
begin
mSprite:=FReady[0];
FReady.Delete(0,1);
w3_setStyle(mSprite.tagRef,’backgroundPosition’,
‘-‘ + IntToStr(getXforChar(FText[FCharIndex])) +’px 0px’);
mSprite.x:=Width;
mSprite.y:=(Height div 2) – (CHAR_SIZE div 2);
mSprite.Update3d;
FChars.add(mSprite);
end;
end;
end;

procedure TForm1.setupChars;
var
cnt: Integer;
x: Integer;
mChar: TW3Sprite;
begin
if FChars.length<1 then
Begin
cnt:=width div CHAR_SIZE;
if (cnt * CHAR_SIZE) < width then
inc(cnt);
inc(cnt);

for x:=0 to cnt-1 do
Begin
mChar:=TW3Sprite.Create(self);
mChar.setTransformFlags(CNT_USE_POS);
mChar.background.fromUrl(‘res/fnt16x16.png’);

w3_setStyle(mChar.tagRef,’backgroundPosition’,’0px 0px’);
mChar.x:=-CHAR_SIZE * 2;
mChar.width:=CHAR_SIZE;
mChar.height:=CHAR_SIZE;
//mChar.color:=clRed;
mChar.Transparent:=True;
mChar.visible:=true;
mChar.update3d;
FReady.add(mChar);
end;
end;
end;

Procedure TForm1.FormActivated;
Begin
inherited;
setupChars;
FTimer.Enabled:=True;
end;

Procedure TForm1.FormDeActivated;
Begin
FTimer.enabled:=False;
inherited;
end;

Procedure TForm1.Resize;
var
dx: Integer;
Begin
inherited;
dx:=(width div 2) – (FLogo.width div 2);
FLogo.setBounds(dx,10,FLogo.Width,FLogo.Height);
FFront.setBounds(0,Height-FFront.height,FFront.width,FFront.height);
FBack01.top:=FFront.top – FBack01.height;
if FCredits<>NIl then
begin
FCredits.top:=Height – (FCredits.height + 10);
FCredits.left:=(Width div 2) – (FCredits.width div 2);
end;
end;

Procedure TForm1.StyleTagObject;
Begin
// Custom styling
End;

end.
[/sourcecode]

demo parallax

Pages

  • About
  • Feature Matrix
  • Forums
  • News
  • Release History
  • Download
  • Showcases
    • The Smart Contest 2013, Round 1 – Graphics
  • Store
  • Documentation
    • Creating your own controls
    • Debugging, exceptions and error handling
    • Differences between Delphi and Smart
    • Get the book
    • Getting started
      • Introduction
      • Local storage, session storage and global storage
      • Application architecture
      • The application object
      • Forms and navigation
      • Message dialogs
      • pmSmart Box Model
      • Themes and styles
    • Layout manager
    • Networking
      • Loading files
      • TW3HttpRequest
      • TW3JSONP
    • Prerequisites
    • Real data, talking to sqLite
    • System requirements
    • Project types
      • Visual project
      • Game project
      • Console project

Archives

  • December 2019
  • December 2018
  • November 2018
  • July 2018
  • June 2018
  • February 2018
  • September 2017
  • April 2017
  • November 2016
  • October 2016
  • September 2016
  • April 2016
  • March 2016
  • January 2016
  • October 2015
  • September 2015
  • July 2015
  • April 2015
  • January 2015
  • December 2014
  • October 2014
  • September 2014
  • August 2014
  • July 2014
  • June 2014
  • March 2014
  • February 2014
  • January 2014
  • December 2013
  • November 2013
  • October 2013
  • August 2013
  • July 2013
  • June 2013
  • May 2013
  • April 2013
  • March 2013
  • February 2013
  • January 2013
  • December 2012
  • November 2012
  • August 2012
  • July 2012
  • June 2012
  • May 2012
  • April 2012
  • March 2012
  • February 2012
  • January 2012
  • November 2011
  • October 2011
  • September 2011

Categories

  • Announcements (25)
  • Developers log (119)
  • Documentation (26)
  • News (104)
  • News and articles (16)

WordPress

  • Register
  • Log in
  • WordPress

Subscribe

  • Entries (RSS)
  • Comments (RSS)
© Optimale Systemer AS