UFO In Space with Fading Tail ver 3.0
#1
In the last UFO demo I posted, I spoke about my concerns with manually adjusting the alpha channel through code as it would remove all current alpha channel data for that image, which doesn't work very well with images that have transparent parts, like the glass dome on the UFO in this demo.

To over come this problem, I created a sprite sheet of 16 UFO's, four across and four down, ranging in the overall opacity from 6.25% to 100%. We do not need to create a 0% opacity UFO as it would never be seen anyway. Now in the screenshot below, you can see the stars behind the glass dome of the UFO, which is the original affect I wanted.

This animated demo not only shows how to do hardware accelerated graphics, but also how to use spritesheets.

Here is the source to this project for your viewing pleasure, but please be sure to download the attachment below to run the demo with graphics.

Code:
' #############################################################################
' #                                                                           #
' #  UFO in space with a tail that fades out.                                 #
' #                                                                           #
' #  Created By:  Walter Whitman                                              #
' #               a.k.a. Waltersmind and The Joyful Programmer                #
' #                                                                           #
' #  Date:  11/15/2016                                                        #
' #                                                                           #
' #  This demo on uses hardware acceleration rending to accomplish the        #
' #  animation, as well a spritesheet.                                        #
' #                                                                           #
' #############################################################################

CONST Radian = 3.141592654 / 180


TYPE UFOS
    x AS INTEGER
    y AS INTEGER
    XOffset AS _UNSIGNED INTEGER
    YOffset AS _UNSIGNED INTEGER
END TYPE

'  SINCE WE KNOW THE NUMBER OF SPRITES ON THE SPRITE SHEET, THEN DIMENSION THE
'  UFO ARRAY WITH THE TOTAL QUANTITY.
DIM UFO(16) AS UFOS

DIM WindowWidth AS _UNSIGNED INTEGER
DIM WindowHeight AS _UNSIGNED INTEGER
DIM WindowTopLeftX AS _UNSIGNED INTEGER
DIM WindowTopLeftY AS _UNSIGNED INTEGER

DIM MainWindow AS LONG
DIM BackgroundImage AS LONG
DIM UFOSpriteSheet AS LONG

DIM UFOwidth AS _UNSIGNED INTEGER
DIM UFOheight AS _UNSIGNED INTEGER
DIM UFOSpriteColumns AS _UNSIGNED _BYTE
DIM UFOSpriteRows AS _UNSIGNED _BYTE

DIM FastSin(360) AS DOUBLE
DIM FastCos(360) AS DOUBLE
DIM SteppingSpeed AS _UNSIGNED _BYTE

DesktopImage& = _SCREENIMAGE

WindowWidth = _WIDTH(DesktopImage&) - 25
WindowHeight = _HEIGHT(DesktopImage&) - 90
WindowTopLeftX = (_WIDTH(DesktopImage&) - WindowWidth) / 2 - 3
WindowTopLeftY = (_HEIGHT(DesktopImage&) - WindowHeight) / 2 - 35

MainWindow = _NEWIMAGE(WindowWidth, WindowHeight, 32)

UFOwidth = 157
UFOheight = 87
UFOSpriteColumns = 4
UFOSpriteRows = 4


'  AN OLD HACK TO REMOVE CONSTANT CALCULATIONS OF COMMON SIN & COS VALUES.
'  WE DO NOT NEED A HIGH-RESOLUTION COS/SIN TABLE HERE.
FOR Angle = 0 TO 359
    FastSin(Angle) = SIN(Angle * Radian)
    FastCos(Angle) = COS(Angle * Radian)
NEXT

'  THIS VALUE TELL THE APP HOW MANY TIMES TO CALCULATE THE NEXT (X,Y) COORDINATES. THIS ALLOWS THE
'  UFO IMAGE TO APPEAR TO SPEED UP A BIT. I COULD OF USE SOME MATH INSTEAD OF A LOOP, BUT I WAS IN
'  A HURRY TO GET THIS POSTED.
SteppingSpeed = 2


SCREEN MainWindow
_SCREENMOVE WindowTopLeftX, WindowTopLeftY

_TITLE "UFO In Space with Fading Tail (Using Hardware Acceleration & Spritesheet) - By: Waltersmind @ TheJoyfulProgrammer.com"


'  Background image is courtesy of NASA.gov.
'  Image URL: http://www.nasa.gov/image-feature/goddard/2016/hubble-peers-into-the-storm
BackgroundImage = _LOADIMAGE("Background_01.jpg", 33)


'  UFO image was created by Waltersmind for The Joyful Programmer
'  IN THIS DEMO, WE WILL LOAD THE UFO IMAGE INTO THE FIRST UFO INDEX AND JUST COPY IT TO THE OTHERS.
'  THIS WILL KEEP US FROM LOADING IT AND THEN FREEING IT AFTER IT IS PUT IN THE OTHER UFO ARRAY INDEXES.
UFOimage = _LOADIMAGE("UFO-SpriteSheet1.png", 33)


'  THIS DEMO USES THE BOWDITCH / LISSAJOUS CURVE
PendulumVerticalAngle = 0
PendulumHorizontalAngle = 0


'  DEFINE THE DATA FOR THE FIRST UFO.
UFO(0).x = WindowWidth / 2 + WindowWidth * SIN(PendulumHorizontalAngle * Radian) * COS(PendulumHorizontalAngle * Radian)
UFO(0).y = WindowHeight / 2 + (WindowHeight - 100) * SIN(PendulumVerticalAngle * Radian)
UFO(0).XOffset = 0
UFO(0).YOffset = 0

'  DEFINE THE DATA FOR ALL THE REST OF THE UFO'S. ALL WE NEED TO DO IS COPY THE (X,Y) COORDINATES AND THE IMAGE
'  USED IN THE FIRST UFO INDEX.
FOR i = 1 TO UBOUND(UFO) - 1
    UFO(i).x = UFO(0).x
    UFO(i).y = UFO(0).y
    UFO(i).XOffset = UFOwidth * (i MOD UFOSpriteColumns)
    UFO(i).YOffset = UFOheight * INT(i / UFOSpriteRows)
NEXT



'  ####  MAIN GAME LOOP  ####
DO

    _LIMIT 60


    '  TURN OFF ALL ERROR CHECKING AND EVENTS (tell QB64 not to add such code to final executable)
    $CHECKING:OFF


    '  DRAW THE BACKGROUND IMAGE
    _PUTIMAGE (0, 0)-(WindowWidth - 1, WindowHeight - 1), BackgroundImage, 0, (0, 0)-(_WIDTH(BackgroundImage) - 1, _HEIGHT(BackgroundImage) - 1)


    '  DRAW ALL UFO'S FROM THE UFO SPRITE SHEET
    FOR i = 0 TO UBOUND(ufo)
        _PUTIMAGE (UFO(i).x - (UFOwidth / 2), UFO(i).y - (UFOheight / 2)), UFOimage, 0, (UFO(i).XOffset, UFO(i).YOffset)-(UFO(i).XOffset + UFOwidth - 1, UFO(i).YOffset + UFOheight - 1)
    NEXT


    '  SINCE EACH UFO UP TO THE ONE BEFORE THE LAST JUST TAKES THE NEXT UFO (X,Y) COORDINATES,
    '  ALL WE NEED TO COPY THE NEXT ONE TO THE CURRENT ONE.
    FOR i = 0 TO UBOUND(ufo) - 1
        UFO(i).x = UFO(i + 1).x
        UFO(i).y = UFO(i + 1).y
    NEXT


    '  CALCULATE THE LAST UFO WITH ALL NEW (X,Y) COORDINATES
    UFO(UBOUND(ufo)).x = WindowWidth / 2 + WindowWidth * SIN(PendulumHorizontalAngle * Radian) * COS(PendulumHorizontalAngle * Radian)
    UFO(UBOUND(ufo)).y = WindowHeight / 2 + (WindowHeight / 2) * SIN(PendulumVerticalAngle * Radian)


    '  A HACK TO SKIP SO MANY STEPS IN OUR ANIMATION. IT HELPS SHOW THE TAIL BETTER
    FOR i = 1 TO SteppingSpeed
        PendulumHorizontalAngle = 1.000013 * PendulumHorizontalAngle + 1.01 '1.0000001# *
        PendulumVerticalAngle = PendulumVerticalAngle + 1
    NEXT


    '  TURN ERROR CHECKING AND EVENTS BACK ON SINCE WE NEED THEM NOW
    $CHECKING:ON


    _DISPLAY


    '  READ THE KEYBOARD TO SEE IF ANY KEY HAS BEEN PRESSED
    k = _KEYHIT


    '  IF THE <ESC> KEY IS PRESSED THEN CLOSED THE PROJECT
    IF k = 27 THEN

        '  FREE BACKGROUND IMAGE
        _FREEIMAGE (BackgroundImage)

        '  EXIT PROJECT TO SYSTEM
        SYSTEM

    END IF

LOOP


Here is a screenshot:




Until the next time... Have fun and enjoy!


Walter Whitman
The Joyful Programmer


Attached Files .zip   UFO_In_Space_With_Tail3.zip (Size: 290.11 KB / Downloads: 40)
Dedicated to empowering computer programming hobbyists, tinkerers, amateurs, and enthusiasts.
profile for Walter Whitman at Stack Overflow, Q&A for professional and enthusiast programmers


Reply
#2
hi Walter,

nice demo!

the code snippet above seems to have some missing closed brackets in these lines (but the .bas file in the download package is fine):
Code:
WindowWidth = _WIDTH(DesktopImage& - 25)

WindowHeight = _HEIGHT(DesktopImage& - 90)

WindowTopLeftX = (_WIDTH(DesktopImage& - WindowWidth)) / 2 - 3

WindowTopLeftY = (_HEIGHT(DesktopImage& - WindowHeight)) / 2 - 35

it also seems to run better for me when i slow down the speed by half and reduce the window size where the UFO flies.

cheers,
a.
I like to program in BASIC
With code that is simple and slick
I learnt it in school
And it is still cool
So it is my number one pick
Reply
#3
@Adrian,

The missing brackets is caused by the mark-up system in this forum, and it was something that was mentioned awhile back. Sadly, there isn't much I can do about it, which is why I uploaded the code with the graphics in the *.ZIP file.

Are you running the demo on an older machine or laptop? The animation is using hardware acceleration (meaning the video card is doing all the drawing) and should be running smoothly as well as fast. I am suprised you are having to slow the animation to make it run better for you.
Dedicated to empowering computer programming hobbyists, tinkerers, amateurs, and enthusiasts.
profile for Walter Whitman at Stack Overflow, Q&A for professional and enthusiast programmers


Reply
#4
Hi Walter,

I didn't realise there was a mark-up problem with the forum. Anyway, I've edited the code snippet in my post and it shows the missing brackets now. Will experiment further to see if the same thing happens again if I upload a similar .bas file.

The animation runs too fast on my pc, so i prefer to slow it down so that it looks better to my eyes. e.g. i didn't realise a penguin was piloting the UFO.
I like to program in BASIC
With code that is simple and slick
I learnt it in school
And it is still cool
So it is my number one pick
Reply
#5
Adrian,

It isn't a problem per-sey, but the fact that the software scans all text in a post, code or not, and replaces specific chunks of text with whatever has been defined. I had corrected a lot of the system, but it is possible I didn't check all the code on the site.

The system does not mess with uploaded files, just text inside a post.

The penguin in the ufo is actually "Squeaky" from the animated movie, "Toy Story".

I actually created the ufo myself in Corel Draw X6, which is what I use at work for most of the artwork and layouts I do on products our clients need printed. Though I am not a graphic designer, I can do enough to make our clients happy.

My grandmother use to call me a "Jack of all Trades, and expert of none" becuase I always tried to dabble in everything I could get my hands on. I've rebuilt alternators and starters for five years, welded for two, did a stint in the Army, drove forklifts, installed capets, sheet rock, did electrical stuff under the guidance of electricians, played a clarinet, cooked in restaurants, cashiered at many places, managed a convenience store (gas station), built and repaired computers, I program computers, do website development, and the list goes on and on.

If you do find any issues with the forum, please let me know. While I did not build this forum software (it's from Mybb), I know a lot about the internals of it. Just like I know the internals of QB64, at least a good bit of it.
Dedicated to empowering computer programming hobbyists, tinkerers, amateurs, and enthusiasts.
profile for Walter Whitman at Stack Overflow, Q&A for professional and enthusiast programmers


Reply
#6
Does the demo require a Windows version of QB64?

The first thing I got when running is the following error:



(followed by another bunch of these). After clicking a few times "Yes", I only see the following:

Reply
#7
@CyberMonkey342,

The demo does not contain any code that is Windows specific. You may have found a bug in QB64. What operating system are you trying to run this in?

The demo uses hardware acceleration, which is the only thing I can think of at the moment that might be causing the issue. Try the following code:

Code:
' #############################################################################
' #                                                                           #
' #  UFO in space with a tail that fades out.                                 #
' #                                                                           #
' #  Created By:  Walter Whitman                                              #
' #               a.k.a. Waltersmind and The Joyful Programmer                #
' #                                                                           #
' #  Date:  11/15/2016                                                        #
' #                                                                           #
' #  This demo on uses hardware acceleration rending to accomplish the        #
' #  animation, as well a spritesheet.                                        #
' #                                                                           #
' #############################################################################

CONST Radian = 3.141592654 / 180


TYPE UFOS
    x AS INTEGER
    y AS INTEGER
    XOffset AS _UNSIGNED INTEGER
    YOffset AS _UNSIGNED INTEGER
END TYPE

'  SINCE WE KNOW THE NUMBER OF SPRITES ON THE SPRITE SHEET, THEN DIMENSION THE
'  UFO ARRAY WITH THE TOTAL QUANTITY.
DIM UFO(16) AS UFOS

DIM WindowWidth AS _UNSIGNED INTEGER
DIM WindowHeight AS _UNSIGNED INTEGER
DIM WindowTopLeftX AS _UNSIGNED INTEGER
DIM WindowTopLeftY AS _UNSIGNED INTEGER

DIM MainWindow AS LONG
DIM BackgroundImage AS LONG
DIM UFOSpriteSheet AS LONG

DIM UFOwidth AS _UNSIGNED INTEGER
DIM UFOheight AS _UNSIGNED INTEGER
DIM UFOSpriteColumns AS _UNSIGNED _BYTE
DIM UFOSpriteRows AS _UNSIGNED _BYTE

DIM FastSin(360) AS DOUBLE
DIM FastCos(360) AS DOUBLE
DIM SteppingSpeed AS _UNSIGNED _BYTE

DesktopImage& = _SCREENIMAGE

WindowWidth = _WIDTH(DesktopImage&) - 25
WindowHeight = _HEIGHT(DesktopImage&) - 90
WindowTopLeftX = (_WIDTH(DesktopImage&) - WindowWidth) / 2 - 3
WindowTopLeftY = (_HEIGHT(DesktopImage&) - WindowHeight) / 2 - 35

MainWindow = _NEWIMAGE(WindowWidth, WindowHeight, 32)

UFOwidth = 157
UFOheight = 87
UFOSpriteColumns = 4
UFOSpriteRows = 4


'  AN OLD HACK TO REMOVE CONSTANT CALCULATIONS OF COMMON SIN & COS VALUES.
'  WE DO NOT NEED A HIGH-RESOLUTION COS/SIN TABLE HERE.
FOR Angle = 0 TO 359
    FastSin(Angle) = SIN(Angle * Radian)
    FastCos(Angle) = COS(Angle * Radian)
NEXT

'  THIS VALUE TELL THE APP HOW MANY TIMES TO CALCULATE THE NEXT (X,Y) COORDINATES. THIS ALLOWS THE
'  UFO IMAGE TO APPEAR TO SPEED UP A BIT. I COULD OF USE SOME MATH INSTEAD OF A LOOP, BUT I WAS IN
'  A HURRY TO GET THIS POSTED.
SteppingSpeed = 2


SCREEN MainWindow
_SCREENMOVE WindowTopLeftX, WindowTopLeftY

_TITLE "UFO In Space with Fading Tail (Using Hardware Acceleration & Spritesheet) - By: Waltersmind @ TheJoyfulProgrammer.com"


'  Background image is courtesy of NASA.gov.
'  Image URL: http://www.nasa.gov/image-feature/goddard/2016/hubble-peers-into-the-storm
BackgroundImage = _LOADIMAGE("Background_01.jpg", 32)


'  UFO image was created by Waltersmind for The Joyful Programmer
'  IN THIS DEMO, WE WILL LOAD THE UFO IMAGE INTO THE FIRST UFO INDEX AND JUST COPY IT TO THE OTHERS.
'  THIS WILL KEEP US FROM LOADING IT AND THEN FREEING IT AFTER IT IS PUT IN THE OTHER UFO ARRAY INDEXES.
UFOimage = _LOADIMAGE("UFO-SpriteSheet1.png", 32)


'  THIS DEMO USES THE BOWDITCH / LISSAJOUS CURVE
PendulumVerticalAngle = 0
PendulumHorizontalAngle = 0


'  DEFINE THE DATA FOR THE FIRST UFO.
UFO(0).x = WindowWidth / 2 + WindowWidth * SIN(PendulumHorizontalAngle * Radian) * COS(PendulumHorizontalAngle * Radian)
UFO(0).y = WindowHeight / 2 + (WindowHeight - 100) * SIN(PendulumVerticalAngle * Radian)
UFO(0).XOffset = 0
UFO(0).YOffset = 0

'  DEFINE THE DATA FOR ALL THE REST OF THE UFO'S. ALL WE NEED TO DO IS COPY THE (X,Y) COORDINATES AND THE IMAGE
'  USED IN THE FIRST UFO INDEX.
FOR i = 1 TO UBOUND(UFO) - 1
    UFO(i).x = UFO(0).x
    UFO(i).y = UFO(0).y
    UFO(i).XOffset = UFOwidth * (i MOD UFOSpriteColumns)
    UFO(i).YOffset = UFOheight * INT(i / UFOSpriteRows)
NEXT



'  ####  MAIN GAME LOOP  ####
DO

    _LIMIT 60


    '  TURN OFF ALL ERROR CHECKING AND EVENTS (tell QB64 not to add such code to final executable)
    $CHECKING:OFF


    '  DRAW THE BACKGROUND IMAGE
    _PUTIMAGE (0, 0)-(WindowWidth - 1, WindowHeight - 1), BackgroundImage, 0, (0, 0)-(_WIDTH(BackgroundImage) - 1, _HEIGHT(BackgroundImage) - 1)


    '  DRAW ALL UFO'S FROM THE UFO SPRITE SHEET
    FOR i = 0 TO UBOUND(ufo)
        _PUTIMAGE (UFO(i).x - (UFOwidth / 2), UFO(i).y - (UFOheight / 2)), UFOimage, 0, (UFO(i).XOffset, UFO(i).YOffset)-(UFO(i).XOffset + UFOwidth - 1, UFO(i).YOffset + UFOheight - 1)
    NEXT


    '  SINCE EACH UFO UP TO THE ONE BEFORE THE LAST JUST TAKES THE NEXT UFO (X,Y) COORDINATES,
    '  ALL WE NEED TO COPY THE NEXT ONE TO THE CURRENT ONE.
    FOR i = 0 TO UBOUND(ufo) - 1
        UFO(i).x = UFO(i + 1).x
        UFO(i).y = UFO(i + 1).y
    NEXT


    '  CALCULATE THE LAST UFO WITH ALL NEW (X,Y) COORDINATES
    UFO(UBOUND(ufo)).x = WindowWidth / 2 + WindowWidth * SIN(PendulumHorizontalAngle * Radian) * COS(PendulumHorizontalAngle * Radian)
    UFO(UBOUND(ufo)).y = WindowHeight / 2 + (WindowHeight / 2) * SIN(PendulumVerticalAngle * Radian)


    '  A HACK TO SKIP SO MANY STEPS IN OUR ANIMATION. IT HELPS SHOW THE TAIL BETTER
    FOR i = 1 TO SteppingSpeed
        PendulumHorizontalAngle = 1.000013 * PendulumHorizontalAngle + 1.01 '1.0000001# *
        PendulumVerticalAngle = PendulumVerticalAngle + 1
    NEXT


    '  TURN ERROR CHECKING AND EVENTS BACK ON SINCE WE NEED THEM NOW
    $CHECKING:ON


    _DISPLAY


    '  READ THE KEYBOARD TO SEE IF ANY KEY HAS BEEN PRESSED
    k = _KEYHIT


    '  IF THE <ESC> KEY IS PRESSED THEN CLOSED THE PROJECT
    IF k = 27 THEN

        '  FREE BACKGROUND IMAGE
        _FREEIMAGE (BackgroundImage)

        '  EXIT PROJECT TO SYSTEM
        SYSTEM

    END IF

LOOP

This will run as software rendered.

All I did to switch from hardware to software was to change two lines:

Quote:BackgroundImage = _LOADIMAGE("Background_01.jpg", 33)

to

Quote:BackgroundImage = _LOADIMAGE("Background_01.jpg", 32)

and this

Quote:UFOimage = _LOADIMAGE("UFO-SpriteSheet1.png", 33)

to

Quote:UFOimage = _LOADIMAGE("UFO-SpriteSheet1.png", 32)

If changing those two lines fixes the issue, then there could be an issue with your video card drivers.
Dedicated to empowering computer programming hobbyists, tinkerers, amateurs, and enthusiasts.
profile for Walter Whitman at Stack Overflow, Q&A for professional and enthusiast programmers


Reply
#8
The same error occurs. It's first line 49 and the following code:
Code:
WindowWidth = _WIDTH(DesktopImage& - 25
WindowHeight = _HEIGHT(DesktopImage& - 90
WindowTopLeftX = (_WIDTH(DesktopImage& - WindowWidth) / 2 - 3
WindowTopLeftY = (_HEIGHT(DesktopImage& - WindowHeight) / 2 - 35

Then line 75:
Code:
SCREEN MainWindow

And finally line 158:
Code:
    _DISPLAY     
(which is weird, because I already used _DISPLAY and it worked ...
Reply
#9
Hi Cybermonkey342,

You may have copied the previous code snippet with the missing brackets. That could have caused your display errors and messages. Try downloading the program package and running that code, or copy the code snippet from Walter's updated post (with the missing brackets reinstated for lines 49-52).
I like to program in BASIC
With code that is simple and slick
I learnt it in school
And it is still cool
So it is my number one pick
Reply
#10
Walter,

You are definitely an expert in more than one trade, your grandmother may have wanted to keep you nicely grounded and humble. Smile

Reminds me of Marisa Tomei's character in "My Cousin Vinny" where she is a totally badass (and cute) automotive expert.
I like to program in BASIC
With code that is simple and slick
I learnt it in school
And it is still cool
So it is my number one pick
Reply
#11
@Adrian,

I just updated that listing today, so all parenthesis's are there now. I guess I missed updating the code in this thread when I made a fix to the system.

I love that movie (My Cousin Vinny)!

On my trade skills, I never wanted to be tied down to one trade. The only reason I have been at the print shop I work at for as long as I have is because I am married and have responsibilities.

There is one type of trade I will not, and can not do professionally. That trade is assembly. I can not move fast enough to produce the quantity of assembled products these corporations require. Plus, it bores me to no end. My biggest problem is that I always have to do different things or I will get bored.

If there is something other than assembly-production, and I am interested in doing it, I will keep working at it until I figure it out.

My grandmother would tell me I need to learn one thing and make a good living at it, and at this point, I am working on that.
Dedicated to empowering computer programming hobbyists, tinkerers, amateurs, and enthusiasts.
profile for Walter Whitman at Stack Overflow, Q&A for professional and enthusiast programmers


Reply
#12
(11-29-2017, 04:06 AM)Adrian Huang Wrote: Hi Cybermonkey342,

You may have copied the previous code snippet with the missing brackets. That could have caused your display errors and messages. Try downloading the program package and running that code, or copy the code snippet from Walter's updated post (with the missing brackets reinstated for lines 49-52).
Nope, I downloaded the ZIP ... I just tried it on Windows 10 and it works perfectly. But on both of my Linux systems (Linux Mint 18.2 64 and 32 bit) it crashes with the same error. Maybe we should use _DESKTOPWIDTH and _DESKTOPHEIGHT for initializing, because I know those are working ...?
Reply
#13
@Cybermonkey342,

I forgot that _SCREENWINDOW image was primarily a Windows only command. Now that makes sense.

However, I wrote this demo before "_DESKTOPWIDTH" and "_DESKTOPHEIGHT" came out.
Dedicated to empowering computer programming hobbyists, tinkerers, amateurs, and enthusiasts.
profile for Walter Whitman at Stack Overflow, Q&A for professional and enthusiast programmers


Reply