Play an image-frame animation
Control playback and respond to frame, completion and failure events.
Animation consumes its configured frame source, including a declared ImageList. FrameChanged is for observing progress; Completed and Failed are terminal outcomes. Pause preserves playback state, while Stop is a distinct command. The sample also includes the PreviousFrame API for manual stepping.
Step 1Prepare a safe practice project#
Extract the archive into a new writable folder, separate from your own application. Open Animation.mcbproj in McBasic™. Keep every declared source, layout, resource and migration file together.
To reconstruct it yourself, create a DesktopApp project and add the files declared below. In the complete project, follow these steps as a guided rebuild: replace each named source file once and Check after all its procedures are present.
Exact project configuration
{
"schemaVersion": 1,
"projectId": "d7ea2638-3161-46ec-8515-9d6fd6764201",
"name": "AnimationSample",
"kind": "DesktopApp",
"ai": {
"storeChatsInProject": false
},
"language": {
"dialect": "McBasic1",
"requireExplicit": true,
"compare": "Binary",
"defaultArrayBase": 0
},
"application": {
"bundleIdentifier": "com.mcbasic.samples.animation",
"version": "0.1.0",
"buildNumber": "1",
"startupFormId": "form-main",
"shutdownMode": "OnStartupFormClosed"
},
"forms": [
{
"id": "form-main",
"typeName": "frmMain",
"layout": "Forms/frmMain.form.json",
"code": "Forms/frmMain.bas"
}
],
"modules": [],
"classes": [],
"tests": [],
"references": [],
"resources": [
{
"name": "Logo",
"path": "Resources/logo.png"
}
],
"targets": [
"osx-arm64"
],
"capabilities": []
}Step 2Build the Form and set its properties#
frmMain
Select the Form first and set its properties. Add containers before their children. These are initial Designer values, not statements to paste into a procedure.
| Form property | Value |
|---|---|
Caption | "Animation — McBasic" |
Width | 560 |
Height | 410 |
MinWidth | 500 |
MinHeight | 360 |
| Type | Name | Parent |
|---|---|---|
| Animation | aniLogo | Form |
| CommandButton | cmdPlay | Form |
| CommandButton | cmdPause | Form |
| CommandButton | cmdNext | Form |
| CommandButton | cmdStop | Form |
| Label | lblStatus | Form |
| ImageList | imgFrames | Component tray |
aniLogo · exact Inspector values
| Property | Value |
|---|---|
Left | 24 |
Top | 24 |
Width | 512 |
Height | 250 |
ImageList | "imgFrames" |
Frames | "first,second,third" |
Interval | 350 |
AutoPlay | True |
Loop | True |
Stretch | "Uniform" |
AccessibleName | "Animated McBasic logo" |
| Anchor edges | Left, Top, Right, Bottom |
cmdPlay · exact Inspector values
| Property | Value |
|---|---|
Left | 24 |
Top | 300 |
Width | 94 |
Height | 34 |
Caption | "Play" |
| Anchor edges | Left, Bottom |
cmdPause · exact Inspector values
| Property | Value |
|---|---|
Left | 128 |
Top | 300 |
Width | 94 |
Height | 34 |
Caption | "Pause" |
| Anchor edges | Left, Bottom |
cmdNext · exact Inspector values
| Property | Value |
|---|---|
Left | 232 |
Top | 300 |
Width | 94 |
Height | 34 |
Caption | "Next" |
| Anchor edges | Left, Bottom |
cmdStop · exact Inspector values
| Property | Value |
|---|---|
Left | 336 |
Top | 300 |
Width | 94 |
Height | 34 |
Caption | "Stop" |
| Anchor edges | Left, Bottom |
lblStatus · exact Inspector values
| Property | Value |
|---|---|
Left | 24 |
Top | 350 |
Width | 512 |
Height | 30 |
Caption | "Ready" |
| Anchor edges | Left, Right, Bottom |
imgFrames · exact Inspector values
| Property | Value |
|---|---|
Images | "first=Logo\nsecond=Logo\nthird=Logo" |
Step 3Connect the events explicitly#
frmMain
| Object | Event | Procedure | Parameters |
|---|---|---|---|
aniLogo | FrameChanged | aniLogo_FrameChanged | FrameChanged() |
aniLogo | Completed | aniLogo_Completed | Completed() |
aniLogo | Failed | aniLogo_Failed | Failed() |
cmdPlay | Click | cmdPlay_Click | Click() |
cmdPause | Click | cmdPause_Click | Click() |
cmdNext | Click | cmdNext_Click | Click() |
cmdStop | Click | cmdStop_Click | Click() |
| Form | Load | Form_Load | () |
Step 4Enter the complete behavior#
Open the named source file. Enter declarations first, then every procedure. Expand a procedure for its full body, or copy the complete file. Helpers are required: do not stop after entering the first Click handler.
Forms/frmMain.bas
Enter these declarations at file scope, before the procedures.
Option ExplicitPrivate Sub Form_Load()
Initialize state before enabling dependent actions. Keep the shared declarations and startup dependencies with this procedure.
Private Sub Form_Load()
lblStatus.Caption = "Frame " + CStr(aniLogo.CurrentFrame) + " of " + CStr(aniLogo.FrameCount)
End SubPrivate Sub aniLogo_FrameChanged()
Enter this helper in the named source file, outside every other procedure. Its callers are included in the same project.
Private Sub aniLogo_FrameChanged()
lblStatus.Caption = "Frame " + CStr(aniLogo.CurrentFrame) + " of " + CStr(aniLogo.FrameCount)
End SubPrivate Sub aniLogo_Completed()
Enter this helper in the named source file, outside every other procedure. Its callers are included in the same project.
Private Sub aniLogo_Completed()
lblStatus.Caption = "Animation completed"
End SubPrivate Sub aniLogo_Failed()
Enter this helper in the named source file, outside every other procedure. Its callers are included in the same project.
Private Sub aniLogo_Failed()
lblStatus.Caption = aniLogo.Error
End SubPrivate Sub cmdPlay_Click()
Enter the complete action, including its input checks and calls to helper procedures.
Private Sub cmdPlay_Click()
aniLogo.Play
End SubPrivate Sub cmdPause_Click()
Enter the complete action, including its input checks and calls to helper procedures.
Private Sub cmdPause_Click()
aniLogo.Pause
End SubPrivate Sub cmdNext_Click()
Enter the complete action, including its input checks and calls to helper procedures.
Private Sub cmdNext_Click()
aniLogo.NextFrame
End SubPrivate Sub cmdStop_Click()
Enter the complete action, including its input checks and calls to helper procedures.
Private Sub cmdStop_Click()
aniLogo.Stop
End SubPrivate Sub ExercisePreviousFrame()
Enter this helper in the named source file, outside every other procedure. Its callers are included in the same project.
Private Sub ExercisePreviousFrame()
aniLogo.PreviousFrame
End SubCopy the complete Forms/frmMain.bas file
Replace the file once; do not append duplicate procedures.
Option Explicit
Private Sub Form_Load()
lblStatus.Caption = "Frame " + CStr(aniLogo.CurrentFrame) + " of " + CStr(aniLogo.FrameCount)
End Sub
Private Sub aniLogo_FrameChanged()
lblStatus.Caption = "Frame " + CStr(aniLogo.CurrentFrame) + " of " + CStr(aniLogo.FrameCount)
End Sub
Private Sub aniLogo_Completed()
lblStatus.Caption = "Animation completed"
End Sub
Private Sub aniLogo_Failed()
lblStatus.Caption = aniLogo.Error
End Sub
Private Sub cmdPlay_Click()
aniLogo.Play
End Sub
Private Sub cmdPause_Click()
aniLogo.Pause
End Sub
Private Sub cmdNext_Click()
aniLogo.NextFrame
End Sub
Private Sub cmdStop_Click()
aniLogo.Stop
End Sub
' Retains the complete public command surface in this compiler example.
Private Sub ExercisePreviousFrame()
aniLogo.PreviousFrame
End SubStep 5Keep resources and storage reproducible#
Keep the following files at their declared relative paths. Apply migrations before the first query. Media and report resources must travel with the build.
| File | Purpose |
|---|---|
Resources/logo.png | Bundled asset / license |
Step 6Check, run and test the result#
Save all files and run Check. Resolve diagnostics before Run. Developer CLI users can work from the extracted folder:
mcbasic check Animation.mcbproj
mcbasic run Animation.mcbprojAcceptance checklist
- Play and observe frame feedback.
- Pause, step a frame and resume.
- Stop and start again.
- Inspect the failure path with an intentionally invalid resource in a disposable copy.
Step 7Make one change and repeat the tests#
Add a Previous button that calls PreviousFrame and verify it at the first frame boundary.
Save a working Git checkpoint first. Change one behavior, Check again and repeat the acceptance checklist. Compare with the downloaded solution if a regression appears.
20f4bfed6b · Build manifest